BOM-2279 : Pylint amnesty for edxnotes,email_marketing, and experiments (#26274)
* lint amnesty for edxnotes,email_marketing, and experiments
This commit is contained in:
@@ -7,11 +7,11 @@ class EdxNotesParseError(Exception):
|
||||
"""
|
||||
An exception that is raised whenever we have issues with data parsing.
|
||||
"""
|
||||
pass
|
||||
pass # lint-amnesty, pylint: disable=unnecessary-pass
|
||||
|
||||
|
||||
class EdxNotesServiceUnavailable(Exception):
|
||||
"""
|
||||
An exception that is raised whenever EdxNotes service is unavailable.
|
||||
"""
|
||||
pass
|
||||
pass # lint-amnesty, pylint: disable=unnecessary-pass
|
||||
|
||||
@@ -44,7 +44,7 @@ class NoteJSONEncoder(JSONEncoder):
|
||||
Custom JSON encoder that encode datetime objects to appropriate time strings.
|
||||
"""
|
||||
# pylint: disable=method-hidden
|
||||
def default(self, obj):
|
||||
def default(self, obj): # lint-amnesty, pylint: disable=arguments-differ
|
||||
if isinstance(obj, datetime):
|
||||
return get_default_time_display(obj)
|
||||
return json.JSONEncoder.default(self, obj)
|
||||
@@ -57,7 +57,7 @@ def get_edxnotes_id_token(user):
|
||||
try:
|
||||
notes_application = Application.objects.get(name=settings.EDXNOTES_CLIENT_NAME)
|
||||
except Application.DoesNotExist:
|
||||
raise ImproperlyConfigured(
|
||||
raise ImproperlyConfigured( # lint-amnesty, pylint: disable=raise-missing-from
|
||||
u'OAuth2 Client with name [{}] does not exist.'.format(settings.EDXNOTES_CLIENT_NAME)
|
||||
)
|
||||
return create_jwt_for_user(
|
||||
@@ -114,7 +114,7 @@ def send_request(user, course_id, page, page_size, path="", text=None):
|
||||
)
|
||||
except RequestException:
|
||||
log.error(u"Failed to connect to edx-notes-api: url=%s, params=%s", url, str(params))
|
||||
raise EdxNotesServiceUnavailable(_("EdxNotes Service is unavailable. Please try again in a few minutes."))
|
||||
raise EdxNotesServiceUnavailable(_("EdxNotes Service is unavailable. Please try again in a few minutes.")) # lint-amnesty, pylint: disable=raise-missing-from
|
||||
|
||||
return response
|
||||
|
||||
@@ -145,7 +145,7 @@ def delete_all_notes_for_user(user):
|
||||
)
|
||||
except RequestException:
|
||||
log.error(u"Failed to connect to edx-notes-api: url=%s, params=%s", url, str(headers))
|
||||
raise EdxNotesServiceUnavailable(_("EdxNotes Service is unavailable. Please try again in a few minutes."))
|
||||
raise EdxNotesServiceUnavailable(_("EdxNotes Service is unavailable. Please try again in a few minutes.")) # lint-amnesty, pylint: disable=raise-missing-from
|
||||
|
||||
return response
|
||||
|
||||
@@ -346,7 +346,7 @@ def get_notes(request, course, page=DEFAULT_PAGE, page_size=DEFAULT_PAGE_SIZE, t
|
||||
collection = json.loads(response.content.decode('utf-8'))
|
||||
except ValueError:
|
||||
log.error(u"Invalid JSON response received from notes api: response_content=%s", response.content)
|
||||
raise EdxNotesParseError(_("Invalid JSON response received from notes api."))
|
||||
raise EdxNotesParseError(_("Invalid JSON response received from notes api.")) # lint-amnesty, pylint: disable=raise-missing-from
|
||||
|
||||
# Verify response dict structure
|
||||
expected_keys = ['total', 'rows', 'num_pages', 'start', 'next', 'previous', 'current_page']
|
||||
@@ -396,7 +396,7 @@ def get_endpoint(api_url, path=""):
|
||||
|
||||
return api_url + path
|
||||
except (AttributeError, KeyError):
|
||||
raise ImproperlyConfigured(_("No endpoint was provided for EdxNotes."))
|
||||
raise ImproperlyConfigured(_("No endpoint was provided for EdxNotes.")) # lint-amnesty, pylint: disable=raise-missing-from
|
||||
|
||||
|
||||
def get_public_endpoint(path=""):
|
||||
|
||||
@@ -30,15 +30,15 @@ from . import helpers
|
||||
from .decorators import edxnotes
|
||||
from .exceptions import EdxNotesParseError, EdxNotesServiceUnavailable
|
||||
from .plugins import EdxNotesTab
|
||||
from openedx.core.djangoapps.oauth_dispatch.jwt import create_jwt_for_user
|
||||
from openedx.core.djangoapps.oauth_dispatch.tests.factories import ApplicationFactory
|
||||
from openedx.core.djangoapps.user_api.models import RetirementState, UserRetirementStatus
|
||||
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, SuperuserFactory, UserFactory
|
||||
from xmodule.modulestore import ModuleStoreEnum
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
|
||||
from xmodule.tabs import CourseTab
|
||||
from openedx.core.djangoapps.oauth_dispatch.jwt import create_jwt_for_user # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from openedx.core.djangoapps.oauth_dispatch.tests.factories import ApplicationFactory # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from openedx.core.djangoapps.user_api.models import RetirementState, UserRetirementStatus # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, SuperuserFactory, UserFactory # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from xmodule.modulestore import ModuleStoreEnum # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from xmodule.modulestore.django import modulestore # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from xmodule.tabs import CourseTab # lint-amnesty, pylint: disable=wrong-import-order
|
||||
|
||||
FEATURES = settings.FEATURES.copy()
|
||||
|
||||
@@ -100,14 +100,14 @@ class EdxNotesDecoratorTest(ModuleStoreTestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(EdxNotesDecoratorTest, self).setUp()
|
||||
super(EdxNotesDecoratorTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
|
||||
ApplicationFactory(name="edx-notes")
|
||||
# Using old mongo because of locator comparison issues (see longer
|
||||
# note below in EdxNotesHelpersTest setUp.
|
||||
self.course = CourseFactory(edxnotes=True, default_store=ModuleStoreEnum.Type.mongo)
|
||||
self.user = UserFactory()
|
||||
self.client.login(username=self.user.username, password=UserFactory._DEFAULT_PASSWORD)
|
||||
self.client.login(username=self.user.username, password=UserFactory._DEFAULT_PASSWORD) # lint-amnesty, pylint: disable=protected-access
|
||||
self.problem = TestProblem(self.course, self.user)
|
||||
|
||||
@patch.dict("django.conf.settings.FEATURES", {'ENABLE_EDXNOTES': True})
|
||||
@@ -205,7 +205,7 @@ class EdxNotesHelpersTest(ModuleStoreTestCase):
|
||||
"""
|
||||
Setup a dummy course content.
|
||||
"""
|
||||
super(EdxNotesHelpersTest, self).setUp()
|
||||
super(EdxNotesHelpersTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
|
||||
# There are many tests that are comparing locators as returned from helper methods. When using
|
||||
# the split modulestore, some of those locators have version and branch information, but the
|
||||
@@ -241,7 +241,7 @@ class EdxNotesHelpersTest(ModuleStoreTestCase):
|
||||
self.child_html_module = self.store.get_item(self.child_html_module.location)
|
||||
|
||||
self.user = UserFactory()
|
||||
self.client.login(username=self.user.username, password=UserFactory._DEFAULT_PASSWORD)
|
||||
self.client.login(username=self.user.username, password=UserFactory._DEFAULT_PASSWORD) # lint-amnesty, pylint: disable=protected-access
|
||||
|
||||
self.request = RequestFactory().request()
|
||||
self.request.user = self.user
|
||||
@@ -978,23 +978,23 @@ class EdxNotesViewsTest(ModuleStoreTestCase):
|
||||
"""
|
||||
def setUp(self):
|
||||
ApplicationFactory(name="edx-notes")
|
||||
super(EdxNotesViewsTest, self).setUp()
|
||||
super(EdxNotesViewsTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
self.course = CourseFactory(edxnotes=True)
|
||||
self.user = UserFactory()
|
||||
CourseEnrollmentFactory(user=self.user, course_id=self.course.id)
|
||||
self.client.login(username=self.user.username, password=UserFactory._DEFAULT_PASSWORD)
|
||||
self.notes_page_url = reverse("edxnotes", args=[text_type(self.course.id)])
|
||||
self.notes_url = reverse("notes", args=[text_type(self.course.id)])
|
||||
self.get_token_url = reverse("get_token", args=[text_type(self.course.id)])
|
||||
self.visibility_url = reverse("edxnotes_visibility", args=[text_type(self.course.id)])
|
||||
CourseEnrollmentFactory(user=self.user, course_id=self.course.id) # lint-amnesty, pylint: disable=no-member
|
||||
self.client.login(username=self.user.username, password=UserFactory._DEFAULT_PASSWORD) # lint-amnesty, pylint: disable=protected-access
|
||||
self.notes_page_url = reverse("edxnotes", args=[text_type(self.course.id)]) # lint-amnesty, pylint: disable=no-member
|
||||
self.notes_url = reverse("notes", args=[text_type(self.course.id)]) # lint-amnesty, pylint: disable=no-member
|
||||
self.get_token_url = reverse("get_token", args=[text_type(self.course.id)]) # lint-amnesty, pylint: disable=no-member
|
||||
self.visibility_url = reverse("edxnotes_visibility", args=[text_type(self.course.id)]) # lint-amnesty, pylint: disable=no-member
|
||||
|
||||
def _get_course_module(self):
|
||||
"""
|
||||
Returns the course module.
|
||||
"""
|
||||
field_data_cache = FieldDataCache([self.course], self.course.id, self.user)
|
||||
field_data_cache = FieldDataCache([self.course], self.course.id, self.user) # lint-amnesty, pylint: disable=no-member
|
||||
return get_module_for_descriptor(
|
||||
self.user, MagicMock(), self.course, field_data_cache, self.course.id, course=self.course
|
||||
self.user, MagicMock(), self.course, field_data_cache, self.course.id, course=self.course # lint-amnesty, pylint: disable=no-member
|
||||
)
|
||||
|
||||
def test_edxnotes_tab(self):
|
||||
@@ -1030,7 +1030,7 @@ class EdxNotesViewsTest(ModuleStoreTestCase):
|
||||
# pylint: disable=unused-argument
|
||||
@patch.dict("django.conf.settings.FEATURES", {"ENABLE_EDXNOTES": True})
|
||||
@patch("lms.djangoapps.edxnotes.views.get_notes", return_value={'results': []})
|
||||
@patch("lms.djangoapps.edxnotes.views.get_course_position", return_value={'display_name': 'Section 1', 'url': 'test_url'})
|
||||
@patch("lms.djangoapps.edxnotes.views.get_course_position", return_value={'display_name': 'Section 1', 'url': 'test_url'}) # lint-amnesty, pylint: disable=line-too-long
|
||||
def test_edxnotes_html_tags_should_not_be_escaped(self, mock_get_notes, mock_position):
|
||||
"""
|
||||
Tests that explicit html tags rendered correctly.
|
||||
@@ -1167,7 +1167,7 @@ class EdxNotesRetireAPITest(ModuleStoreTestCase):
|
||||
"""
|
||||
def setUp(self):
|
||||
ApplicationFactory(name="edx-notes")
|
||||
super(EdxNotesRetireAPITest, self).setUp()
|
||||
super(EdxNotesRetireAPITest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
|
||||
# setup relevant states
|
||||
RetirementState.objects.create(state_name='PENDING', state_execution_order=1)
|
||||
@@ -1282,7 +1282,7 @@ class EdxNotesPluginTest(ModuleStoreTestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(EdxNotesPluginTest, self).setUp()
|
||||
super(EdxNotesPluginTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
self.course = CourseFactory.create(edxnotes=True)
|
||||
self.user = UserFactory()
|
||||
CourseEnrollmentFactory.create(user=self.user, course_id=self.course.id)
|
||||
|
||||
@@ -177,11 +177,11 @@ def notes(request, course_id):
|
||||
except (EdxNotesParseError, EdxNotesServiceUnavailable) as err:
|
||||
return JsonResponseBadRequest({"error": text_type(err)}, status=500)
|
||||
|
||||
return HttpResponse(json.dumps(notes_info, cls=NoteJSONEncoder), content_type="application/json")
|
||||
return HttpResponse(json.dumps(notes_info, cls=NoteJSONEncoder), content_type="application/json") # lint-amnesty, pylint: disable=http-response-with-content-type-json, http-response-with-json-dumps
|
||||
|
||||
|
||||
@login_required
|
||||
def get_token(request, course_id):
|
||||
def get_token(request, course_id): # lint-amnesty, pylint: disable=unused-argument
|
||||
"""
|
||||
Get JWT ID-Token, in case you need new one.
|
||||
"""
|
||||
|
||||
@@ -15,4 +15,4 @@ class EmailMarketingConfig(AppConfig):
|
||||
|
||||
def ready(self):
|
||||
# Register the signal handlers.
|
||||
from . import signals # pylint: disable=unused-variable
|
||||
from . import signals # lint-amnesty, pylint: disable=unused-import, unused-variable
|
||||
|
||||
@@ -17,7 +17,7 @@ from six import text_type
|
||||
|
||||
from common.djangoapps import third_party_auth
|
||||
from common.djangoapps.course_modes.models import CourseMode
|
||||
from edx_toggles.toggles import LegacyWaffleSwitchNamespace
|
||||
from edx_toggles.toggles import LegacyWaffleSwitchNamespace # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from lms.djangoapps.email_marketing.tasks import (
|
||||
get_email_cookies_via_sailthru,
|
||||
update_course_enrollment,
|
||||
@@ -114,7 +114,7 @@ def add_email_marketing_cookies(sender, response=None, user=None,
|
||||
except SailthruClientError as exc:
|
||||
log.error(u"Exception attempting to obtain cookie from Sailthru: %s", text_type(exc))
|
||||
return response
|
||||
except Exception:
|
||||
except Exception: # lint-amnesty, pylint: disable=broad-except
|
||||
log.error(u"Exception Connecting to celery task for %s", user.email)
|
||||
return response
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ SAILTHRU_LIST_CACHE_KEY = "email.marketing.cache"
|
||||
# TODO: Remove in AA-607
|
||||
@shared_task(bind=True)
|
||||
@set_code_owner_attribute
|
||||
def get_email_cookies_via_sailthru(self, user_email, post_parms):
|
||||
def get_email_cookies_via_sailthru(self, user_email, post_parms): # lint-amnesty, pylint: disable=unused-argument
|
||||
"""
|
||||
Adds/updates Sailthru cookie information for a new user.
|
||||
Args:
|
||||
@@ -47,7 +47,7 @@ def get_email_cookies_via_sailthru(self, user_email, post_parms):
|
||||
sailthru_response = sailthru_client.api_post("user", post_parms)
|
||||
except SailthruClientError as exc:
|
||||
log.error(u"Exception attempting to obtain cookie from Sailthru: %s", six.text_type(exc))
|
||||
raise SailthruClientError
|
||||
raise SailthruClientError # lint-amnesty, pylint: disable=raise-missing-from
|
||||
|
||||
if sailthru_response.is_ok():
|
||||
if 'keys' in sailthru_response.json and 'cookie' in sailthru_response.json['keys']:
|
||||
@@ -310,7 +310,7 @@ def _retryable_sailthru_error(error):
|
||||
See: https://getstarted.sailthru.com/new-for-developers-overview/api/api-response-errors/
|
||||
"""
|
||||
code = error.get_error_code()
|
||||
return code == 9 or code == 43
|
||||
return code == 9 or code == 43 # lint-amnesty, pylint: disable=consider-using-in
|
||||
|
||||
|
||||
# TODO: Remove in AA-607
|
||||
@@ -335,7 +335,7 @@ def update_course_enrollment(self, email, course_key, mode, site=None):
|
||||
|
||||
try:
|
||||
sailthru_client = SailthruClient(config.sailthru_key, config.sailthru_secret)
|
||||
except:
|
||||
except: # lint-amnesty, pylint: disable=bare-except
|
||||
return
|
||||
|
||||
send_template = config.sailthru_enroll_template
|
||||
|
||||
@@ -20,7 +20,7 @@ from sailthru.sailthru_error import SailthruClientError
|
||||
from sailthru.sailthru_response import SailthruResponse
|
||||
from testfixtures import LogCapture
|
||||
|
||||
from lms.djangoapps.email_marketing.tasks import (
|
||||
from lms.djangoapps.email_marketing.tasks import ( # lint-amnesty, pylint: disable=unused-import
|
||||
_create_user_list,
|
||||
_get_list_from_email_marketing_provider,
|
||||
_get_or_create_user_list,
|
||||
@@ -31,7 +31,7 @@ from lms.djangoapps.email_marketing.tasks import (
|
||||
)
|
||||
from openedx.core.djangoapps.lang_pref import LANGUAGE_KEY
|
||||
from common.djangoapps.student.models import Registration, User
|
||||
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory, UserProfileFactory
|
||||
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory, UserProfileFactory # lint-amnesty, pylint: disable=unused-import
|
||||
from common.djangoapps.util.json_request import JsonResponse
|
||||
|
||||
from ..models import EmailMarketingConfiguration
|
||||
@@ -92,7 +92,7 @@ class EmailMarketingTests(TestCase):
|
||||
|
||||
self.site = Site.objects.get_current()
|
||||
self.request.site = self.site
|
||||
super(EmailMarketingTests, self).setUp()
|
||||
super(EmailMarketingTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
|
||||
@freeze_time(datetime.datetime.now())
|
||||
@patch('lms.djangoapps.email_marketing.signals.crum.get_current_request')
|
||||
@@ -131,7 +131,7 @@ class EmailMarketingTests(TestCase):
|
||||
'cookies': {'anonymous_interest': 'cookie_content'},
|
||||
'id': TEST_EMAIL,
|
||||
'vars': {'last_login_date': ANY}})
|
||||
self.assertTrue('sailthru_hid' in response.cookies)
|
||||
self.assertTrue('sailthru_hid' in response.cookies) # lint-amnesty, pylint: disable=wrong-assert-type
|
||||
self.assertEqual(response.cookies['sailthru_hid'].value, "test_cookie")
|
||||
|
||||
@patch('sailthru.sailthru_client.SailthruClient.api_post')
|
||||
@@ -167,15 +167,15 @@ class EmailMarketingTests(TestCase):
|
||||
})
|
||||
mock_sailthru.return_value = SailthruResponse(JsonResponse({'keys': {'cookiexx': 'test_cookie'}}))
|
||||
add_email_marketing_cookies(None, response=response, user=self.user)
|
||||
self.assertFalse('sailthru_hid' in response.cookies)
|
||||
self.assertFalse('sailthru_hid' in response.cookies) # lint-amnesty, pylint: disable=wrong-assert-type
|
||||
|
||||
mock_sailthru.return_value = SailthruResponse(JsonResponse({'error': "error", "errormsg": "errormsg"}))
|
||||
add_email_marketing_cookies(None, response=response, user=self.user)
|
||||
self.assertFalse('sailthru_hid' in response.cookies)
|
||||
self.assertFalse('sailthru_hid' in response.cookies) # lint-amnesty, pylint: disable=wrong-assert-type
|
||||
|
||||
mock_sailthru.side_effect = SailthruClientError
|
||||
add_email_marketing_cookies(None, response=response, user=self.user)
|
||||
self.assertFalse('sailthru_hid' in response.cookies)
|
||||
self.assertFalse('sailthru_hid' in response.cookies) # lint-amnesty, pylint: disable=wrong-assert-type
|
||||
|
||||
@patch('lms.djangoapps.email_marketing.tasks.log.error')
|
||||
@patch('lms.djangoapps.email_marketing.tasks.SailthruClient.api_post')
|
||||
@@ -615,7 +615,7 @@ class SailthruTests(TestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(SailthruTests, self).setUp()
|
||||
super(SailthruTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
self.user = UserFactory()
|
||||
self.course_id = CourseKey.from_string('edX/toy/2012_Fall')
|
||||
self.course_url = 'http://lms.testserver.fake/courses/edX/toy/2012_Fall/info'
|
||||
|
||||
@@ -9,7 +9,7 @@ from .models import ExperimentData, ExperimentKeyValue
|
||||
|
||||
|
||||
@admin.register(ExperimentData)
|
||||
class ExperimentDataAdmin(admin.ModelAdmin):
|
||||
class ExperimentDataAdmin(admin.ModelAdmin): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
list_display = ('user', 'experiment_id', 'key',)
|
||||
list_filter = ('experiment_id',)
|
||||
ordering = ('experiment_id', 'user', 'key',)
|
||||
@@ -19,7 +19,7 @@ class ExperimentDataAdmin(admin.ModelAdmin):
|
||||
|
||||
|
||||
@admin.register(ExperimentKeyValue)
|
||||
class ExperimentKeyValueAdmin(admin.ModelAdmin):
|
||||
class ExperimentKeyValueAdmin(admin.ModelAdmin): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
list_display = ('experiment_id', 'key',)
|
||||
list_filter = ('experiment_id',)
|
||||
ordering = ('experiment_id', 'key',)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# lint-amnesty, pylint: disable=missing-module-docstring
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ from lms.djangoapps.experiments.models import ExperimentData, ExperimentKeyValue
|
||||
from common.djangoapps.student.tests.factories import UserFactory
|
||||
|
||||
|
||||
class ExperimentDataFactory(factory.DjangoModelFactory):
|
||||
class ExperimentDataFactory(factory.DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
class Meta(object):
|
||||
model = ExperimentData
|
||||
|
||||
@@ -20,7 +20,7 @@ class ExperimentDataFactory(factory.DjangoModelFactory):
|
||||
value = factory.Faker('word')
|
||||
|
||||
|
||||
class ExperimentKeyValueFactory(factory.DjangoModelFactory):
|
||||
class ExperimentKeyValueFactory(factory.DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
class Meta(object):
|
||||
model = ExperimentKeyValue
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ class IsStaffOrOwner(permissions.IsStaffOrOwner):
|
||||
# Non-staff users can only create data for themselves.
|
||||
if view.action == 'create':
|
||||
username = request.user.username
|
||||
return super(IsStaffOrOwner, self).has_permission(request, view) or (
|
||||
return super(IsStaffOrOwner, self).has_permission(request, view) or ( # lint-amnesty, pylint: disable=super-with-arguments
|
||||
username == request.data.get('user', username))
|
||||
|
||||
# The view will handle filtering for the current user
|
||||
|
||||
@@ -11,7 +11,7 @@ from .models import ExperimentData, ExperimentKeyValue
|
||||
User = get_user_model() # pylint:disable=invalid-name
|
||||
|
||||
|
||||
class ExperimentDataCreateSerializer(serializers.ModelSerializer):
|
||||
class ExperimentDataCreateSerializer(serializers.ModelSerializer): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
user = serializers.SlugRelatedField(slug_field='username', default=serializers.CurrentUserDefault(), required=False,
|
||||
queryset=User.objects.all())
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ Tests of experiment functionality
|
||||
from datetime import timedelta
|
||||
from decimal import Decimal
|
||||
from django.utils.timezone import now
|
||||
from unittest import TestCase
|
||||
from unittest import TestCase # lint-amnesty, pylint: disable=wrong-import-order
|
||||
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from lms.djangoapps.course_blocks.transformers.tests.helpers import ModuleStoreTestCase
|
||||
from lms.djangoapps.courseware import courses
|
||||
from lms.djangoapps.courseware import courses # lint-amnesty, pylint: disable=unused-import
|
||||
from lms.djangoapps.experiments.utils import (
|
||||
get_course_entitlement_price_and_sku,
|
||||
get_experiment_user_metadata_context,
|
||||
@@ -27,7 +27,7 @@ class ExperimentUtilsTests(ModuleStoreTestCase, TestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(ExperimentUtilsTests, self).setUp()
|
||||
super(ExperimentUtilsTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
|
||||
# Create a course run
|
||||
self.run_a_price = '86.00'
|
||||
@@ -100,7 +100,7 @@ class ExperimentUtilsTests(ModuleStoreTestCase, TestCase):
|
||||
def test_price_and_sku_from_course(self):
|
||||
entitlements = [self.entitlement_a]
|
||||
course_a = {'key': 'UQx+ENGYCAPx', 'entitlements': entitlements}
|
||||
courses = [course_a]
|
||||
courses = [course_a] # lint-amnesty, pylint: disable=redefined-outer-name
|
||||
|
||||
price, skus = get_program_price_and_skus(courses)
|
||||
expected_price = u'$199.23'
|
||||
@@ -113,7 +113,7 @@ class ExperimentUtilsTests(ModuleStoreTestCase, TestCase):
|
||||
course_runs = [self.course_run_a]
|
||||
course_a = {'key': 'UQx+ENGY1x', 'course_runs': course_runs}
|
||||
course_b = {'key': 'UQx+ENGYCAPx', 'entitlements': entitlements}
|
||||
courses = [course_a, course_b]
|
||||
courses = [course_a, course_b] # lint-amnesty, pylint: disable=redefined-outer-name
|
||||
|
||||
price, skus = get_program_price_and_skus(courses)
|
||||
expected_price = u'$285.23'
|
||||
@@ -123,9 +123,9 @@ class ExperimentUtilsTests(ModuleStoreTestCase, TestCase):
|
||||
self.assertIn(self.entitlement_a_sku, skus)
|
||||
|
||||
def test_get_experiment_user_metadata_context(self):
|
||||
course = CourseFactory.create(start=now() - timedelta(days=30), pacing_type="instructor_paced", course_duration=None, upgrade_price='Free',
|
||||
upgrade_link=None, enrollment_mode=None, audit_access_deadline=None, program_key_fields=None, schedule_start=None,
|
||||
enrollment_time=None, dynamic_upgrade_deadline=None, course_upgrade_deadline=None, course_key_fields={'org': 'org.0', 'course': 'course_0', 'run': 'Run_0'})
|
||||
course = CourseFactory.create(start=now() - timedelta(days=30), pacing_type="instructor_paced", course_duration=None, upgrade_price='Free', # lint-amnesty, pylint: disable=line-too-long
|
||||
upgrade_link=None, enrollment_mode=None, audit_access_deadline=None, program_key_fields=None, schedule_start=None, # lint-amnesty, pylint: disable=line-too-long
|
||||
enrollment_time=None, dynamic_upgrade_deadline=None, course_upgrade_deadline=None, course_key_fields={'org': 'org.0', 'course': 'course_0', 'run': 'Run_0'}) # lint-amnesty, pylint: disable=line-too-long
|
||||
user = UserFactory()
|
||||
context = get_experiment_user_metadata_context(course, user)
|
||||
CourseEnrollmentFactory(course_id=course.id, user=user)
|
||||
|
||||
@@ -15,11 +15,11 @@ from django.utils.timezone import now
|
||||
from django.test.utils import override_settings
|
||||
from django.urls import reverse
|
||||
from lms.djangoapps.course_blocks.transformers.tests.helpers import ModuleStoreTestCase
|
||||
from mock import patch
|
||||
from rest_framework.test import APITestCase
|
||||
from mock import patch # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from rest_framework.test import APITestCase # lint-amnesty, pylint: disable=wrong-import-order
|
||||
|
||||
from lms.djangoapps.experiments.factories import ExperimentDataFactory, ExperimentKeyValueFactory
|
||||
from lms.djangoapps.experiments.models import ExperimentData, ExperimentKeyValue
|
||||
from lms.djangoapps.experiments.models import ExperimentData, ExperimentKeyValue # lint-amnesty, pylint: disable=unused-import
|
||||
from lms.djangoapps.experiments.serializers import ExperimentDataSerializer
|
||||
from common.djangoapps.student.tests.factories import UserFactory
|
||||
|
||||
@@ -28,16 +28,16 @@ from xmodule.modulestore.tests.factories import CourseFactory
|
||||
CROSS_DOMAIN_REFERER = 'https://ecommerce.edx.org'
|
||||
|
||||
|
||||
class ExperimentDataViewSetTests(APITestCase, ModuleStoreTestCase):
|
||||
class ExperimentDataViewSetTests(APITestCase, ModuleStoreTestCase): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
|
||||
def assert_data_created_for_user(self, user, method='post', status=201):
|
||||
def assert_data_created_for_user(self, user, method='post', status=201): # lint-amnesty, pylint: disable=missing-function-docstring
|
||||
url = reverse('api_experiments:v0:data-list')
|
||||
data = {
|
||||
'experiment_id': 1,
|
||||
'key': 'foo',
|
||||
'value': 'bar',
|
||||
}
|
||||
self.client.login(username=user.username, password=UserFactory._DEFAULT_PASSWORD)
|
||||
self.client.login(username=user.username, password=UserFactory._DEFAULT_PASSWORD) # lint-amnesty, pylint: disable=protected-access
|
||||
response = getattr(self.client, method)(url, data)
|
||||
self.assertEqual(response.status_code, status)
|
||||
|
||||
@@ -57,7 +57,7 @@ class ExperimentDataViewSetTests(APITestCase, ModuleStoreTestCase):
|
||||
|
||||
ExperimentDataFactory()
|
||||
datum = ExperimentDataFactory(user=user)
|
||||
self.client.login(username=user.username, password=UserFactory._DEFAULT_PASSWORD)
|
||||
self.client.login(username=user.username, password=UserFactory._DEFAULT_PASSWORD) # lint-amnesty, pylint: disable=protected-access
|
||||
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
@@ -67,7 +67,7 @@ class ExperimentDataViewSetTests(APITestCase, ModuleStoreTestCase):
|
||||
""" Users should be able to filter by the experiment_id and key fields. """
|
||||
url = reverse('api_experiments:v0:data-list')
|
||||
user = UserFactory()
|
||||
self.client.login(username=user.username, password=UserFactory._DEFAULT_PASSWORD)
|
||||
self.client.login(username=user.username, password=UserFactory._DEFAULT_PASSWORD) # lint-amnesty, pylint: disable=protected-access
|
||||
|
||||
experiment_id = 1
|
||||
ExperimentDataFactory()
|
||||
@@ -99,12 +99,12 @@ class ExperimentDataViewSetTests(APITestCase, ModuleStoreTestCase):
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 401)
|
||||
|
||||
self.client.login(username=user.username, password=UserFactory._DEFAULT_PASSWORD)
|
||||
self.client.login(username=user.username, password=UserFactory._DEFAULT_PASSWORD) # lint-amnesty, pylint: disable=protected-access
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
other_user = UserFactory()
|
||||
self.client.login(username=other_user.username, password=UserFactory._DEFAULT_PASSWORD)
|
||||
self.client.login(username=other_user.username, password=UserFactory._DEFAULT_PASSWORD) # lint-amnesty, pylint: disable=protected-access
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
@@ -122,7 +122,7 @@ class ExperimentDataViewSetTests(APITestCase, ModuleStoreTestCase):
|
||||
'key': 'foo',
|
||||
'value': 'bar',
|
||||
}
|
||||
self.client.login(username=user.username, password=UserFactory._DEFAULT_PASSWORD)
|
||||
self.client.login(username=user.username, password=UserFactory._DEFAULT_PASSWORD) # lint-amnesty, pylint: disable=protected-access
|
||||
|
||||
# Users can create data for themselves
|
||||
response = self.client.post(url, data)
|
||||
@@ -162,11 +162,11 @@ class ExperimentDataViewSetTests(APITestCase, ModuleStoreTestCase):
|
||||
response = self.client.patch(url, data)
|
||||
self.assertEqual(response.status_code, 401)
|
||||
|
||||
self.client.login(username=user.username, password=UserFactory._DEFAULT_PASSWORD)
|
||||
self.client.login(username=user.username, password=UserFactory._DEFAULT_PASSWORD) # lint-amnesty, pylint: disable=protected-access
|
||||
response = self.client.patch(url, data)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
self.client.login(username=other_user.username, password=UserFactory._DEFAULT_PASSWORD)
|
||||
self.client.login(username=other_user.username, password=UserFactory._DEFAULT_PASSWORD) # lint-amnesty, pylint: disable=protected-access
|
||||
response = self.client.patch(url, data)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
@@ -197,7 +197,7 @@ class ExperimentCrossDomainTests(APITestCase):
|
||||
"""Tests for handling cross-domain requests"""
|
||||
|
||||
def setUp(self):
|
||||
super(ExperimentCrossDomainTests, self).setUp()
|
||||
super(ExperimentCrossDomainTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
self.client = self.client_class(enforce_csrf_checks=True)
|
||||
|
||||
@cross_domain_config
|
||||
@@ -264,7 +264,7 @@ class ExperimentCrossDomainTests(APITestCase):
|
||||
)
|
||||
|
||||
|
||||
class ExperimentKeyValueViewSetTests(APITestCase):
|
||||
class ExperimentKeyValueViewSetTests(APITestCase): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
|
||||
def test_permissions(self):
|
||||
""" Staff access is required for write operations. """
|
||||
@@ -283,7 +283,7 @@ class ExperimentKeyValueViewSetTests(APITestCase):
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
user = UserFactory(is_staff=False)
|
||||
self.client.login(username=user.username, password=UserFactory._DEFAULT_PASSWORD)
|
||||
self.client.login(username=user.username, password=UserFactory._DEFAULT_PASSWORD) # lint-amnesty, pylint: disable=protected-access
|
||||
|
||||
response = self.client.put(url, {})
|
||||
self.assertEqual(response.status_code, 403)
|
||||
@@ -303,7 +303,7 @@ class ExperimentUserMetaDataViewTests(APITestCase, ModuleStoreTestCase):
|
||||
lookup_user = UserFactory()
|
||||
lookup_course = CourseFactory.create(start=now() - timedelta(days=30))
|
||||
call_args = [lookup_user.username, lookup_course.id]
|
||||
self.client.login(username=lookup_user.username, password=UserFactory._DEFAULT_PASSWORD)
|
||||
self.client.login(username=lookup_user.username, password=UserFactory._DEFAULT_PASSWORD) # lint-amnesty, pylint: disable=protected-access
|
||||
|
||||
response = self.client.get(reverse('api_experiments:user_metadata', args=call_args))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
@@ -315,7 +315,7 @@ class ExperimentUserMetaDataViewTests(APITestCase, ModuleStoreTestCase):
|
||||
call_args = [lookup_user.username, lookup_course.id]
|
||||
staff_user = UserFactory(is_staff=True)
|
||||
|
||||
self.client.login(username=staff_user.username, password=UserFactory._DEFAULT_PASSWORD)
|
||||
self.client.login(username=staff_user.username, password=UserFactory._DEFAULT_PASSWORD) # lint-amnesty, pylint: disable=protected-access
|
||||
|
||||
response = self.client.get(reverse('api_experiments:user_metadata', args=call_args))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
@@ -337,8 +337,8 @@ class ExperimentUserMetaDataViewTests(APITestCase, ModuleStoreTestCase):
|
||||
""" Request fails when not course not found """
|
||||
lookup_user = UserFactory()
|
||||
lookup_course = CourseFactory.create(start=now() - timedelta(days=30))
|
||||
call_args = [lookup_user.username, lookup_course.id]
|
||||
self.client.login(username=lookup_user.username, password=UserFactory._DEFAULT_PASSWORD)
|
||||
call_args = [lookup_user.username, lookup_course.id] # lint-amnesty, pylint: disable=unused-variable
|
||||
self.client.login(username=lookup_user.username, password=UserFactory._DEFAULT_PASSWORD) # lint-amnesty, pylint: disable=protected-access
|
||||
bogus_course_name = str(lookup_course.id) + '_FOOBAR'
|
||||
|
||||
call_args_with_bogus_course = [lookup_user.username, bogus_course_name]
|
||||
|
||||
@@ -13,7 +13,7 @@ from rest_framework.test import APITestCase
|
||||
|
||||
from common.djangoapps.course_modes.models import CourseMode
|
||||
from common.djangoapps.course_modes.tests.factories import CourseModeFactory
|
||||
from edx_toggles.toggles.testutils import override_waffle_flag
|
||||
from edx_toggles.toggles.testutils import override_waffle_flag # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from lms.djangoapps.course_blocks.transformers.tests.helpers import ModuleStoreTestCase
|
||||
from lms.djangoapps.experiments.views_custom import MOBILE_UPSELL_FLAG
|
||||
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
|
||||
@@ -22,7 +22,7 @@ from xmodule.modulestore.tests.factories import CourseFactory
|
||||
CROSS_DOMAIN_REFERER = 'https://ecommerce.edx.org'
|
||||
|
||||
|
||||
class Rev934LoggedOutTests(APITestCase):
|
||||
class Rev934LoggedOutTests(APITestCase): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
def test_not_logged_in(self):
|
||||
"""Test mobile app upsell API is not available if not logged in"""
|
||||
url = reverse('api_experiments:rev_934')
|
||||
@@ -40,7 +40,7 @@ class Rev934Tests(APITestCase, ModuleStoreTestCase):
|
||||
cls.url = reverse('api_experiments:rev_934')
|
||||
|
||||
def setUp(self):
|
||||
super(Rev934Tests, self).setUp()
|
||||
super(Rev934Tests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
self.user = UserFactory(username='robot-mue-1-6pnjv') # Username that hashes to bucket 1
|
||||
self.client.login(
|
||||
username=self.user.username,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# lint-amnesty, pylint: disable=missing-module-docstring
|
||||
from contextlib import contextmanager
|
||||
|
||||
from mock import patch
|
||||
|
||||
@@ -12,7 +12,7 @@ from opaque_keys import InvalidKeyError
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
|
||||
from common.djangoapps.course_modes.models import format_course_price, get_cosmetic_verified_display_price, CourseMode
|
||||
from edx_toggles.toggles import LegacyWaffleFlag, LegacyWaffleFlagNamespace
|
||||
from edx_toggles.toggles import LegacyWaffleFlag, LegacyWaffleFlagNamespace # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from common.djangoapps.entitlements.models import CourseEntitlement
|
||||
from lms.djangoapps.commerce.utils import EcommerceService
|
||||
from lms.djangoapps.courseware.access import has_staff_access_to_preview_mode
|
||||
@@ -271,7 +271,7 @@ def get_experiment_user_metadata_context(course, user):
|
||||
enrollment = None
|
||||
# TODO: clean up as part of REVO-28 (START)
|
||||
user_enrollments = None
|
||||
audit_enrollments = None
|
||||
audit_enrollments = None # lint-amnesty, pylint: disable=unused-variable
|
||||
has_non_audit_enrollments = False
|
||||
context = {}
|
||||
if course is not None:
|
||||
|
||||
@@ -4,16 +4,16 @@ Experimentation views
|
||||
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.db import transaction
|
||||
from django.db import transaction # lint-amnesty, pylint: disable=unused-import
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from django.http import Http404
|
||||
from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication
|
||||
from edx_rest_framework_extensions.auth.session.authentication import SessionAuthenticationAllowInactiveUser
|
||||
from lms.djangoapps.courseware import courses
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from rest_framework import permissions, viewsets
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from opaque_keys.edx.keys import CourseKey # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from rest_framework import permissions, viewsets # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from rest_framework.response import Response # lint-amnesty, pylint: disable=unused-import, wrong-import-order
|
||||
from rest_framework.views import APIView # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from common.djangoapps.util.json_request import JsonResponse
|
||||
|
||||
from lms.djangoapps.experiments import filters, serializers
|
||||
@@ -28,10 +28,10 @@ User = get_user_model() # pylint: disable=invalid-name
|
||||
|
||||
class ExperimentCrossDomainSessionAuth(SessionAuthenticationAllowInactiveUser, SessionAuthenticationCrossDomainCsrf):
|
||||
"""Session authentication that allows inactive users and cross-domain requests. """
|
||||
pass
|
||||
pass # lint-amnesty, pylint: disable=unnecessary-pass
|
||||
|
||||
|
||||
class ExperimentDataViewSet(viewsets.ModelViewSet):
|
||||
class ExperimentDataViewSet(viewsets.ModelViewSet): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
authentication_classes = (JwtAuthentication, ExperimentCrossDomainSessionAuth,)
|
||||
filter_backends = (DjangoFilterBackend,)
|
||||
filterset_class = filters.ExperimentDataFilter
|
||||
@@ -42,14 +42,14 @@ class ExperimentDataViewSet(viewsets.ModelViewSet):
|
||||
|
||||
def filter_queryset(self, queryset):
|
||||
queryset = queryset.filter(user=self.request.user)
|
||||
return super(ExperimentDataViewSet, self).filter_queryset(queryset)
|
||||
return super(ExperimentDataViewSet, self).filter_queryset(queryset) # lint-amnesty, pylint: disable=super-with-arguments
|
||||
|
||||
def get_serializer_class(self):
|
||||
if self.action == 'create':
|
||||
return serializers.ExperimentDataCreateSerializer
|
||||
return serializers.ExperimentDataSerializer
|
||||
|
||||
def create_or_update(self, request, *args, **kwargs):
|
||||
def create_or_update(self, request, *args, **kwargs): # lint-amnesty, pylint: disable=missing-function-docstring
|
||||
# If we have a primary key, treat this as a regular update request
|
||||
if self.kwargs.get('pk'):
|
||||
return self.update(request, *args, **kwargs)
|
||||
@@ -67,14 +67,14 @@ class ExperimentDataViewSet(viewsets.ModelViewSet):
|
||||
except ExperimentData.DoesNotExist:
|
||||
pass
|
||||
|
||||
self.action = 'create'
|
||||
self.action = 'create' # lint-amnesty, pylint: disable=attribute-defined-outside-init
|
||||
return self.create(request, *args, **kwargs)
|
||||
|
||||
def _cache_users(self, usernames):
|
||||
users = User.objects.filter(username__in=usernames)
|
||||
self._cached_users = {user.username: user for user in users}
|
||||
|
||||
def _get_user(self, username):
|
||||
def _get_user(self, username): # lint-amnesty, pylint: disable=missing-function-docstring
|
||||
user = self._cached_users.get(username)
|
||||
|
||||
if not user:
|
||||
@@ -84,7 +84,7 @@ class ExperimentDataViewSet(viewsets.ModelViewSet):
|
||||
return user
|
||||
|
||||
|
||||
class ExperimentKeyValueViewSet(viewsets.ModelViewSet):
|
||||
class ExperimentKeyValueViewSet(viewsets.ModelViewSet): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
authentication_classes = (JwtAuthentication, ExperimentCrossDomainSessionAuth,)
|
||||
filter_backends = (DjangoFilterBackend,)
|
||||
filterset_class = filters.ExperimentKeyValueFilter
|
||||
@@ -93,7 +93,7 @@ class ExperimentKeyValueViewSet(viewsets.ModelViewSet):
|
||||
serializer_class = serializers.ExperimentKeyValueSerializer
|
||||
|
||||
|
||||
class UserMetaDataView(APIView):
|
||||
class UserMetaDataView(APIView): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
authentication_classes = (JwtAuthentication, ExperimentCrossDomainSessionAuth,)
|
||||
permission_classes = (IsStaffOrReadOnlyForSelf,)
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from common.djangoapps.course_modes.models import get_cosmetic_verified_display_price
|
||||
from edx_toggles.toggles import LegacyWaffleFlag, LegacyWaffleFlagNamespace
|
||||
from edx_toggles.toggles import LegacyWaffleFlag, LegacyWaffleFlagNamespace # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from lms.djangoapps.commerce.utils import EcommerceService
|
||||
from lms.djangoapps.courseware.utils import can_show_verified_upgrade
|
||||
from lms.djangoapps.experiments.stable_bucketing import stable_bucketing_hash_group
|
||||
|
||||
Reference in New Issue
Block a user