Skip to content
Snippets Groups Projects
Unverified Commit 7fba045c authored by Feanil Patel's avatar Feanil Patel Committed by GitHub
Browse files

Merge branch 'master' into feanil/fix_xmodule_video_tests

parents 76c578df f07fae6e
No related branches found
No related tags found
No related merge requests found
Showing
with 483 additions and 62 deletions
......@@ -39,7 +39,7 @@ class RequireJSPathOverridesTest(TestCase):
def test_requirejs_path_overrides(self):
result = render_require_js_path_overrides(self.OVERRIDES)
# To make the string comparision easy remove the whitespaces
self.assertEqual(list(map(str.strip, result.splitlines())), self.OVERRIDES_JS)
self.assertCountEqual(list(map(str.strip, result.splitlines())), self.OVERRIDES_JS)
@skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in LMS')
......
......@@ -32,7 +32,7 @@ class Command(BaseCommand):
csv_path = options['csv_path']
if csv_path:
with open(csv_path) as csv_file:
with open(csv_path, 'rb') as csv_file:
self.unenroll_users(csv_file)
else:
csv_file = BulkUnenrollConfiguration.current().csv_file
......
......@@ -96,7 +96,7 @@ class BulkUnenrollTests(SharedModuleStoreTestCase):
lines += str(enrollment.user.id) + "," + enrollment.user.username + "," + \
enrollment.user.email + "," + str(enrollment.course.id) + "\n"
csv_file = SimpleUploadedFile(name='test.csv', content=lines, content_type='text/csv')
csv_file = SimpleUploadedFile(name='test.csv', content=lines.encode('utf-8'), content_type='text/csv')
BulkUnenrollConfiguration.objects.create(enabled=True, csv_file=csv_file)
call_command("bulk_unenroll")
......@@ -110,14 +110,14 @@ class BulkUnenrollTests(SharedModuleStoreTestCase):
for enrollment in self.enrollments:
username = enrollment.user.username
if username in users_unenrolled:
users_unenrolled[username].append(str(enrollment.course.id))
users_unenrolled[username].append(str(enrollment.course.id).encode('utf-8'))
else:
users_unenrolled[username] = [str(enrollment.course.id)]
users_unenrolled[username] = [str(enrollment.course.id).encode('utf-8')]
lines += str(enrollment.user.id) + "," + username + "," + \
enrollment.user.email + "," + str(enrollment.course.id) + "\n"
csv_file = SimpleUploadedFile(name='test.csv', content=lines, content_type='text/csv')
csv_file = SimpleUploadedFile(name='test.csv', content=lines.encode('utf-8'), content_type='text/csv')
BulkUnenrollConfiguration.objects.create(enabled=True, csv_file=csv_file)
with LogCapture(LOGGER_NAME) as log:
......
......@@ -100,7 +100,7 @@ class CapaTargetedFeedbackTest(unittest.TestCase):
problem.student_answers = {'1_2_1': 'choice_3'}
the_html = problem.get_html()
without_new_lines = the_html.replace("\n", "")
without_new_lines = the_html.replace("\\n", "").replace("\n", "")
# pylint: disable=line-too-long
self.assertRegexpMatches(without_new_lines, r"<targetedfeedback explanation-id=\"feedback3\" role=\"group\" aria-describedby=\"1_2_1-legend\">\s*<span class=\"sr\">Incorrect</span>.*3rd WRONG solution")
self.assertNotRegexpMatches(without_new_lines, r"feedback1|feedback2|feedbackC")
......@@ -114,7 +114,7 @@ class CapaTargetedFeedbackTest(unittest.TestCase):
problem.student_answers = {'1_2_1': 'choice_0'}
the_html = problem.get_html()
without_new_lines = the_html.replace("\n", "")
without_new_lines = the_html.replace("\\n", "").replace("\n", "")
# pylint: disable=line-too-long
self.assertRegexpMatches(without_new_lines, r"<targetedfeedback explanation-id=\"feedback1\" role=\"group\" aria-describedby=\"1_2_1-legend\">\s*<span class=\"sr\">Incorrect</span>.*1st WRONG solution")
self.assertRegexpMatches(without_new_lines, r"<div>\{.*'1_solution_1'.*\}</div>")
......@@ -127,7 +127,7 @@ class CapaTargetedFeedbackTest(unittest.TestCase):
problem.student_answers = {'1_2_1': 'choice_2'}
the_html = problem.get_html()
without_new_lines = the_html.replace("\n", "")
without_new_lines = the_html.replace("\\n", "").replace("\n", "")
# pylint: disable=line-too-long
self.assertRegexpMatches(without_new_lines,
r"<targetedfeedback explanation-id=\"feedbackC\" role=\"group\" aria-describedby=\"1_2_1-legend\">\s*<span class=\"sr\">Correct</span>.*Feedback on your correct solution...")
......
......@@ -4,6 +4,7 @@ Tests for sequence module.
# pylint: disable=no-member
from __future__ import absolute_import
import ast
import json
from datetime import timedelta
......@@ -195,10 +196,10 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
extra_context=dict(specific_masquerade=True),
)
self.assertIn("seq_module.html", html)
self.assertIn(
"'banner_text': u'Because the due date has passed, "
"this assignment is hidden from the learner.'",
html
html = self.get_context_dict_from_string(html)
self.assertEqual(
'Because the due date has passed, this assignment is hidden from the learner.',
html['banner_text']
)
def test_hidden_content_self_paced_past_due_before_end(self):
......@@ -223,31 +224,35 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
Assert sequence content is gated
"""
self.assertIn("seq_module.html", html)
self.assertIn("'banner_text': None", html)
self.assertIn("'items': []", html)
self.assertIn("'gated': True", html)
self.assertIn("'prereq_url': 'PrereqUrl'", html)
self.assertIn("'prereq_section_name': 'PrereqSectionName'", html)
self.assertIn("'gated_section_name': u'{}'".format(six.text_type(sequence.display_name)), html)
self.assertIn("'next_url': 'NextSequential'", html)
self.assertIn("'prev_url': 'PrevSequential'", html)
html = self.get_context_dict_from_string(html)
self.assertIsNone(html['banner_text'])
self.assertEqual([], html['items'])
self.assertTrue(html['gated_content']['gated'])
self.assertEqual('PrereqUrl', html['gated_content']['prereq_url'])
self.assertEqual('PrereqSectionName', html['gated_content']['prereq_section_name'])
self.assertIn(
six.text_type(sequence.display_name),
html['gated_content']['gated_section_name']
)
self.assertEqual('NextSequential', html['next_url'])
self.assertEqual('PrevSequential', html['prev_url'])
def _assert_prereq(self, html, sequence):
"""
Assert sequence is a prerequisite with unfulfilled gates
"""
self.assertIn("seq_module.html", html)
self.assertIn(
"'banner_text': u'This section is a prerequisite. "
"You must complete this section in order to unlock additional content.'",
html
html = self.get_context_dict_from_string(html)
self.assertEqual(
"This section is a prerequisite. You must complete this section in order to unlock additional content.",
html['banner_text']
)
self.assertIn("'gated': False", html)
self.assertIn(six.text_type(sequence.location), html)
self.assertIn("'prereq_url': None", html)
self.assertIn("'prereq_section_name': None", html)
self.assertIn("'next_url': 'NextSequential'", html)
self.assertIn("'prev_url': 'PrevSequential'", html)
self.assertFalse(html['gated_content']['gated'])
self.assertEqual(six.text_type(sequence.location), html['item_id'])
self.assertIsNone(html['gated_content']['prereq_url'])
self.assertIsNone(html['gated_content']['prereq_section_name'])
self.assertEqual('NextSequential', html['next_url'])
self.assertEqual('PrevSequential', html['prev_url'])
def _assert_ungated(self, html, sequence):
"""
......@@ -295,7 +300,6 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
self.sequence_1_2,
extra_context=dict(next_url='NextSequential', prev_url='PrevSequential'),
)
# assert that content and preq banner is shown
self._assert_prereq(html, self.sequence_1_2)
......@@ -338,3 +342,11 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
{'usage_key': usage_key}
)
self.assertIs(completion_return, None)
def get_context_dict_from_string(self, data):
"""
Retrieve dictionary from string.
"""
# Replace tuple and un-necessary info from inside string and get the dictionary.
cleaned_data = data.replace("(('seq_module.html',\n", '').replace("),\n {})", '').strip()
return ast.literal_eval(cleaned_data)
......@@ -1171,7 +1171,9 @@ class VideoBlockIndexingTestCase(unittest.TestCase):
self.assertFalse(validation.empty) # Validation contains some warning/message
self.assertTrue(validation.summary)
self.assertEqual(StudioValidationMessage.WARNING, validation.summary.type)
self.assertIn(expected_msg, validation.summary.text)
self.assertIn(
expected_msg, validation.summary.text.replace('Urdu, Esperanto', 'Esperanto, Urdu')
)
@ddt.data(
(
......
No preview for this file type
module.exports = {
extends: 'eslint-config-edx',
root: true,
settings: {
'import/resolver': {
webpack: {
config: 'webpack.dev.config.js',
},
},
},
};
import { getAuthenticatedAPIClient } from '@edx/frontend-auth';
import { NewRelicLoggingService } from '@edx/frontend-logging';
const apiClient = getAuthenticatedAPIClient({
appBaseUrl: process.env.LMS_ROOT_URL,
authBaseUrl: process.env.LMS_ROOT_URL,
loginUrl: `${process.env.LMS_ROOT_URL}/login`,
logoutUrl: `${process.env.LMS_ROOT_URL}/logout`,
csrfTokenApiPath: '/csrf/api/v1/token',
refreshAccessTokenEndpoint: `${process.env.LMS_ROOT_URL}/login_refresh`,
accessTokenCookieName: process.env.JWT_AUTH_COOKIE_HEADER_PAYLOAD,
userInfoCookieName: process.env.EDXMKTG_USER_INFO_COOKIE_NAME,
loggingService: NewRelicLoggingService,
});
export default apiClient;
module.exports = {
extends: 'eslint-config-edx',
root: true,
settings: {
'import/resolver': {
webpack: {
config: 'webpack.dev.config.js',
},
},
},
};
import { getLearnerPortalLinks } from '@edx/frontend-enterprise';
import apiClient from '../apiClient';
function CustomUserMenuLinks() {
// Inject enterprise learner portal links
getLearnerPortalLinks(apiClient).then((learnerPortalLinks) => {
const $dashboardLink = $('#user-menu .dashboard');
const classNames = 'mobile-nav-item dropdown-item dropdown-nav-item';
for (let i = 0; i < learnerPortalLinks.length; i += 1) {
const link = learnerPortalLinks[i];
$dashboardLink.after( // xss-lint: disable=javascript-jquery-insertion
`<div class="${classNames}"><a href="${link.url}" role="menuitem">${link.title} Dashboard</a></div>`,
);
}
});
}
export { CustomUserMenuLinks }; // eslint-disable-line import/prefer-default-export
import React, { Component } from 'react';
import { getLearnerPortalLinks } from '@edx/frontend-enterprise';
import { StatusAlert } from '@edx/paragon';
import apiClient from '../apiClient';
const LOCAL_STORAGE_KEY = 'has-viewed-enterprise-learner-portal-banner';
function getAlertHtml(learnerPortalLinks) {
let html = '';
for (let i = 0; i < learnerPortalLinks.length; i += 1) {
const link = learnerPortalLinks[i];
html += `<div>
${link.title} has a dedicated page where you can see all of your sponsored courses.
Go to <a href="${link.url}">your learner portal</a>.
</div>`;
}
return html;
}
function setViewedBanner() {
window.localStorage.setItem(LOCAL_STORAGE_KEY, true);
}
function hasViewedBanner() {
window.localStorage.getItem(LOCAL_STORAGE_KEY);
}
class EnterpriseLearnerPortalBanner extends Component {
constructor(props) {
super(props);
this.onClose = this.onClose.bind(this);
this.state = {
open: false,
alertHtml: '',
};
}
componentDidMount() {
if (!hasViewedBanner()) {
getLearnerPortalLinks(apiClient).then((learnerPortalLinks) => {
this.setState({
open: true,
alertHtml: getAlertHtml(learnerPortalLinks),
});
});
}
}
onClose() {
this.setState({ open: false });
setViewedBanner();
}
render() {
const { alertHtml, open } = this.state;
if (open) {
return (
<div className="edx-enterprise-learner-portal-banner-wrapper">
<StatusAlert
className={['edx-enterprise-learner-portal-banner']}
open={open}
// eslint-disable-next-line react/no-danger
dialog={(<span dangerouslySetInnerHTML={{ __html: alertHtml }} />)}
onClose={this.onClose}
/>
</div>
);
}
return null;
}
}
export { EnterpriseLearnerPortalBanner }; // eslint-disable-line import/prefer-default-export
......@@ -73,6 +73,7 @@
@import 'features/_unsupported-browser-alert';
@import 'features/content-type-gating';
@import 'features/course-duration-limits';
@import 'features/enterprise-learner-portal-banner';
// search
@import 'search/search';
......
......@@ -33,6 +33,7 @@
@import 'features/course-sock';
@import 'features/course-upgrade-message';
@import 'features/content-type-gating';
@import 'features/enterprise-learner-portal-banner';
// Responsive Design
......
......@@ -25,6 +25,7 @@ $static-path: '../..';
@import 'features/course-sock';
@import 'features/course-upgrade-message';
@import 'features/course-duration-limits';
@import 'features/enterprise-learner-portal-banner';
// Individual Pages
......
$enterprise-learner-portal-banner-background-color: #d9edf7 !default;
$enterprise-learner-portal-banner-text-color: #4e4e4e !default;
$enterprise-learner-portal-banner-cta-base: #0075b4 !default;
$enterprise-learner-portal-banner-cta-hover: #075683 !default;
.edx-enterprise-learner-portal-banner-wrapper {
background: $enterprise-learner-portal-banner-background-color;
box-sizing: border-box;
/** Base Styles - start **/
text-align: left;
line-height: 1.5;
font: {
family: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif;
size: 1rem;
weight: 400;
}
.alert {
position: relative;
padding: 0.75rem 1.25rem;
}
.alert-dismissible {
.close {
position: absolute;
top: 0;
right: 0;
padding: 0.75rem 1.25rem;
background: transparent;
border: 0;
text-shadow: 0 1px 0 #fff;
opacity: 0.5;
float: right;
line-height: 1;
font: {
size: 1.5rem;
weight: 700;
}
}
.btn {
display: inline-block;
text-align: center;
white-space: nowrap;
vertical-align: middle;
box-shadow: none;
}
}
/** Base Styles - end **/
.edx-enterprise-learner-portal-banner {
box-sizing: border-box;
display: flex;
justify-content: space-between;
max-width: 1200px;
min-width: 0;
margin: 0 auto;
background: inherit;
border: none;
.policy-link {
color: $enterprise-learner-portal-banner-cta-base;
text-decoration: underline;
&:focus,
&:hover {
color: $enterprise-learner-portal-banner-cta-hover;
border: none;
}
}
.alert-dialog {
margin-right: 30px;
color: $enterprise-learner-portal-banner-text-color;
}
.btn.close {
color: $enterprise-learner-portal-banner-cta-base;
&:focus,
&:hover {
color: $enterprise-learner-portal-banner-cta-hover;
cursor: pointer;
}
}
}
}
\ No newline at end of file
## mako
<%page expression_filter="h"/>
<%namespace name='static' file='static_content.html'/>
<%namespace name='static' file='../static_content.html'/>
<%!
from django.conf import settings
......@@ -22,6 +22,12 @@ resume_block = retrieve_last_sitewide_block_completed(self.real_user)
displayname = get_enterprise_learner_generic_name(request) or username
%>
<%static:webpack entry="CustomUserMenuLinks">
$(document).ready(function() {
CustomUserMenuLinks();
});
</%static:webpack>
<div class="nav-item hidden-mobile">
<a href="${reverse('dashboard')}" class="menu-title">
<img class="user-image-frame" src="${profile_image_url}" alt="">
......@@ -37,7 +43,7 @@ displayname = get_enterprise_learner_generic_name(request) or username
% if resume_block:
<div class="mobile-nav-item dropdown-item dropdown-nav-item"><a href="${resume_block}" role="menuitem">${_("Resume your last course")}</a></div>
% endif
<div class="mobile-nav-item dropdown-item dropdown-nav-item"><a href="${reverse('dashboard')}" role="menuitem">${_("Dashboard")}</a></div>
<div class="mobile-nav-item dropdown-item dropdown-nav-item dashboard"><a href="${reverse('dashboard')}" role="menuitem">${_("Dashboard")}</a></div>
<div class="mobile-nav-item dropdown-item dropdown-nav-item"><a href="${reverse('learner_profile', kwargs={'username': username})}" role="menuitem">${_("Profile")}</a></div>
<div class="mobile-nav-item dropdown-item dropdown-nav-item"><a href="${reverse('account_settings')}" role="menuitem">${_("Account")}</a></div>
% if should_redirect_to_order_history_microfrontend():
......
......@@ -4,6 +4,7 @@
Tests for js_utils.py
"""
from __future__ import absolute_import
import re
import six.moves.html_parser # pylint: disable=import-error
import json
from unittest import TestCase
......@@ -97,14 +98,14 @@ class TestJSUtils(TestCase):
parsed from json where applicable.
"""
test_dict = {
'test_string': u'test-=&\\;\'"<>☃'.encode(encoding='utf-8'),
'test_string': u'test-=&\\;\'"<>☃',
'test_tuple': (1, 2, 3),
'test_number': 3.5,
'test_bool': False,
}
template = Template(
"""
u"""
<%!
import json
from openedx.core.djangolib.js_utils import (
......@@ -140,25 +141,28 @@ class TestJSUtils(TestCase):
r"&#34;test_tuple&#34;: [1, 2, 3], &#34;test_string&#34;: "
r"&#34;test-=&amp;\\;&#39;\&#34;&lt;&gt;\u2603&#34;}"
)
expected_attr_json_for_html = "data-test-dict='" + expected_json_for_html + "'"
self._validate_expectation_of_json_for_html(test_dict, expected_json_for_html)
self.assertIn(expected_attr_json_for_html, out)
self.assertIn("&#34;test_tuple&#34;: [1, 2, 3]", out)
self.assertIn("&#34;test_number&#34;: 3.5", out)
self.assertIn("&#34;test_bool&#34;: false", out)
self.assertIn("&#34;test_string&#34;: &#34;test-=&amp;\\\\;&#39;\\&#34;&lt;&gt;\\u2603&#34", out)
self.assertIn(u"data-test-string='test-=&amp;\\;&#39;&#34;&lt;&gt;☃'", out)
self.assertIn("data-test-tuple='[1, 2, 3]'", out)
self.assertIn("data-test-number='3.5'", out)
self.assertIn("data-test-bool='false'", out)
expected_string_for_js_in_dict = r'''test-=\u0026\\;'\"\u003c\u003e\u2603'''
self._validate_expectation_of_string_for_js(test_dict['test_string'], expected_string_for_js_in_dict)
self.assertIn(
(
'var test_dict = {"test_bool": false, "test_number": 3.5, '
'"test_tuple": [1, 2, 3], "test_string": "' + expected_string_for_js_in_dict + '"}'
), out)
expected_string_for_js = r"test\u002D\u003D\u0026\u005C\u003B\u0027\u0022\u003C\u003E☃"
location_of_dict_in_out = re.search("var test_dict.*}", out)
var_dict_in_out = out[location_of_dict_in_out.span()[0]:location_of_dict_in_out.span()[1]]
self.assertIn('"test_number": 3.5', var_dict_in_out)
self.assertIn('"test_string": "test-=\\u0026\\\\;\'\\"\\u003c\\u003e\\u2603"', var_dict_in_out)
self.assertIn('"test_tuple": [1, 2, 3]', var_dict_in_out)
self.assertIn('"test_bool": false', var_dict_in_out)
expected_string_for_js = u"test\\u002D\\u003D\\u0026\\u005C\\u003B\\u0027\\u0022\\u003C\\u003E☃"
self._validate_expectation_of_string_for_js(test_dict['test_string'], expected_string_for_js)
self.assertIn(
"var test_string = '" + expected_string_for_js.decode(encoding='utf-8') + "'",
out)
self.assertIn("var test_string = '" + expected_string_for_js + "'", out)
self.assertIn("var test_none_string = ''", out)
self.assertIn("var test_tuple = [1, 2, 3]", out)
self.assertIn("var test_number = 3.5", out)
......@@ -188,7 +192,7 @@ class TestJSUtils(TestCase):
# tuples become arrays in json, so it is parsed to a list that is
# switched back to a tuple before comparing
parsed_expected_dict['test_tuple'] = tuple(parsed_expected_dict['test_tuple'])
self.assertEqual(test_dict['test_string'].decode(encoding='utf-8'), parsed_expected_dict['test_string'])
self.assertEqual(test_dict['test_string'], parsed_expected_dict['test_string'])
self.assertEqual(test_dict['test_tuple'], parsed_expected_dict['test_tuple'])
self.assertEqual(test_dict['test_number'], parsed_expected_dict['test_number'])
self.assertEqual(test_dict['test_bool'], parsed_expected_dict['test_bool'])
......@@ -209,4 +213,4 @@ class TestJSUtils(TestCase):
"""
parsed_expected_string = json.loads('"' + expected_string_for_js + '"')
self.assertEqual(test_string.decode(encoding='utf-8'), parsed_expected_string)
self.assertEqual(test_string, parsed_expected_string)
......@@ -8,6 +8,8 @@ import mock
import ddt
import httpretty
from six.moves.urllib.parse import parse_qs # pylint: disable=import-error
from consent.models import DataSharingConsent
from django.conf import settings
from django.contrib.auth.models import User
......@@ -395,15 +397,16 @@ class TestEnterpriseApi(EnterpriseServiceMockMixin, CacheIsolationTestCase):
course_id = 'course-v1:edX+DemoX+Demo_Course'
return_to = 'info'
expected_url = (
'/enterprise/grant_data_sharing_permissions?course_id=course-v1%3AedX%2BDemoX%2BDemo_'
'Course&failure_url=http%3A%2F%2Flocalhost%3A8000%2Fdashboard%3Fconsent_failed%3Dcou'
'rse-v1%253AedX%252BDemoX%252BDemo_Course&enterprise_customer_uuid=cf246b88-d5f6-4908'
'-a522-fc307e0b0c59&next=http%3A%2F%2Flocalhost%3A8000%2Fcourses%2Fcourse-v1%3AedX%2B'
'DemoX%2BDemo_Course%2Finfo'
)
expected_url_args = {
'course_id': ['course-v1:edX+DemoX+Demo_Course'],
'failure_url': ['http://localhost:8000/dashboard?consent_failed=course-v1%3AedX%2BDemoX%2BDemo_Course'],
'enterprise_customer_uuid': ['cf246b88-d5f6-4908-a522-fc307e0b0c59'],
'next': ['http://localhost:8000/courses/course-v1:edX+DemoX+Demo_Course/info']
}
actual_url = get_enterprise_consent_url(request_mock, course_id, return_to=return_to)
self.assertEqual(actual_url, expected_url)
actual_url_args = parse_qs(actual_url.split('/enterprise/grant_data_sharing_permissions?')[1])
self.assertEqual(actual_url_args, expected_url_args)
@ddt.data(
(False, {'real': 'enterprise', 'uuid': ''}, 'course', [], [], "", ""),
......
......@@ -66,6 +66,59 @@
"resolved": "https://registry.npmjs.org/@edx/edx-proctoring/-/edx-proctoring-1.5.0.tgz",
"integrity": "sha512-RiNjAgh8ZMX0D5gfN2R09a0RBs/R/Blfs/DiqhLmvCSvyCoeMDGANrDDQXv1w5blxxSJbz8a2awSZkwpv6gWNQ=="
},
"@edx/frontend-auth": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/@edx/frontend-auth/-/frontend-auth-6.0.2.tgz",
"integrity": "sha512-37qMrdzwe02PzLQMF4q2ov7POGM3laWtouHK8BiLL7Q2DhFBxe0IULWAZiEJGvSVBEpMDFfcG+J1s33NiIpUfA==",
"requires": {
"@edx/frontend-logging": "2.1.0",
"axios": "0.18.1",
"camelcase-keys": "5.2.0",
"jwt-decode": "2.2.0",
"pubsub-js": "1.7.0",
"snakecase-keys": "2.1.0",
"universal-cookie": "3.1.0",
"url-parse": "1.4.7"
},
"dependencies": {
"@edx/frontend-logging": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@edx/frontend-logging/-/frontend-logging-2.1.0.tgz",
"integrity": "sha512-IN0Bgh0/1Ax3TMPfZztqzdJchW4B5Px9PT4V9uu6TMj2Cj8el1CV3jrSA4Idg8C3CAkFZ/EHjmaFVCxgJ9aXVA=="
},
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
},
"camelcase-keys": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-5.2.0.tgz",
"integrity": "sha512-mSM/OQKD1HS5Ll2AXxeaHSdqCGC/QQ8IrgTbKYA/rxnC36thBKysfIr9+OVBWuW17jyZF4swHkjtglawgBmVFg==",
"requires": {
"camelcase": "5.3.1",
"map-obj": "3.1.0",
"quick-lru": "1.1.0"
}
},
"map-obj": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-3.1.0.tgz",
"integrity": "sha512-Xg1iyYz/+iIW6YoMldux47H/e5QZyDSB41Kb0ev+YYHh3FJnyyzY0vTk/WbVeWcCvdXd70cOriUBmhP8alUFBA=="
},
"universal-cookie": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-3.1.0.tgz",
"integrity": "sha512-sP6WuFgqIUro7ikgI2ndrsw9Ro+YvVBe5O9cQfWnjTicpLaSMUEUUDjQF8m8utzWF2ONl7tRkcZd7v4n6NnzjQ==",
"requires": {
"@types/cookie": "0.3.3",
"@types/object-assign": "4.0.30",
"cookie": "0.3.1",
"object-assign": "4.1.1"
}
}
}
},
"@edx/frontend-component-cookie-policy-banner": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@edx/frontend-component-cookie-policy-banner/-/frontend-component-cookie-policy-banner-1.0.0.tgz",
......@@ -137,6 +190,16 @@
}
}
},
"@edx/frontend-enterprise": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@edx/frontend-enterprise/-/frontend-enterprise-1.0.2.tgz",
"integrity": "sha512-Xv5R8qpAmg4qr2B4EJpCJrBbgNISPoQbGjK31cS9wWz8u28lhAmsgltKaRKqTD92DPi+uGam3feJ2QhAwLqJqQ=="
},
"@edx/frontend-logging": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@edx/frontend-logging/-/frontend-logging-3.0.1.tgz",
"integrity": "sha512-kRDsPbTUxNfZdnC4KN5HratS/7bkCYv/gyvUnBcuPbiONXwSuriNIVAKCepldvhg1DTwLqQMXh+Qw6vo2r048A=="
},
"@edx/mockprock": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@edx/mockprock/-/mockprock-1.0.2.tgz",
......@@ -272,12 +335,22 @@
"resolved": "https://registry.npmjs.org/@sambego/storybook-styles/-/storybook-styles-1.0.0.tgz",
"integrity": "sha512-n0SqZwDewUDRaStEcoNMiYy9qovaLVStsh4Gb2dc2LLiG3IIK0UXdeR1N7puVuRihJq/192uOyGPCjZ/NAteuA=="
},
"@types/cookie": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.3.3.tgz",
"integrity": "sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow=="
},
"@types/node": {
"version": "10.5.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.5.2.tgz",
"integrity": "sha512-m9zXmifkZsMHZBOyxZWilMwmTlpC8x5Ty360JKTiXvlXZfBWYpsg9ZZvP/Ye+iZUh+Q+MxDLjItVTWIsfwz+8Q==",
"dev": true
},
"@types/object-assign": {
"version": "4.0.30",
"resolved": "https://registry.npmjs.org/@types/object-assign/-/object-assign-4.0.30.tgz",
"integrity": "sha1-iUk3HVqZ9Dge4PHfCpt6GH4H5lI="
},
"abab": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz",
......@@ -905,6 +978,22 @@
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
"integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4="
},
"axios": {
"version": "0.18.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz",
"integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==",
"requires": {
"follow-redirects": "1.5.10",
"is-buffer": "2.0.4"
},
"dependencies": {
"is-buffer": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
"integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A=="
}
}
},
"axobject-query": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-0.1.0.tgz",
......@@ -5203,6 +5292,24 @@
"resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz",
"integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I="
},
"follow-redirects": {
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
"requires": {
"debug": "3.1.0"
},
"dependencies": {
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
"ms": "2.0.0"
}
}
}
},
"font-awesome": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz",
......@@ -7837,6 +7944,11 @@
"integrity": "sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE=",
"dev": true
},
"jwt-decode": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-2.2.0.tgz",
"integrity": "sha1-fYa9VmefWM5qhHBKZX3TkruoGnk="
},
"karma": {
"version": "0.13.22",
"resolved": "https://registry.npmjs.org/karma/-/karma-0.13.22.tgz",
......@@ -10491,6 +10603,11 @@
"randombytes": "2.0.6"
}
},
"pubsub-js": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/pubsub-js/-/pubsub-js-1.7.0.tgz",
"integrity": "sha512-Pb68P9qFZxnvDipHMuj9oT1FoIgBcXJ9C9eWdHCLZAnulaUoJ3+Y87RhGMYilWpun6DMWVmvK70T4RP4drZMSA=="
},
"punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
......@@ -10525,11 +10642,15 @@
"resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
"integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM="
},
"querystringify": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz",
"integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA=="
},
"quick-lru": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz",
"integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=",
"dev": true
"integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g="
},
"raf": {
"version": "3.4.0",
......@@ -11295,8 +11416,7 @@
"requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
"dev": true
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
},
"reselect": {
"version": "3.0.1",
......@@ -12185,6 +12305,22 @@
"resolved": "https://registry.npmjs.org/slick-carousel/-/slick-carousel-1.8.1.tgz",
"integrity": "sha512-XB9Ftrf2EEKfzoQXt3Nitrt/IPbT+f1fgqBdoxO3W/+JYvtEOW6EgxnWfr9GH6nmULv7Y2tPmEX3koxThVmebA=="
},
"snakecase-keys": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/snakecase-keys/-/snakecase-keys-2.1.0.tgz",
"integrity": "sha512-oQSiCIgNCwixBf8Kxgv0SPo67zQSutIEymAk/dkgcdZEOMPvGMGPua/WwYGPG4LLHArGGews3CB3zEEfqlMk2g==",
"requires": {
"map-obj": "3.0.0",
"to-snake-case": "1.0.0"
},
"dependencies": {
"map-obj": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-3.0.0.tgz",
"integrity": "sha512-Ot+2wruG8WqTbJngDxz0Ifm03y2pO4iL+brq/l+yEkGjUza03BnMQqX2XT//Jls8MOOl2VTHviAoLX+/nq/HXw=="
}
}
},
"snapdragon": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
......@@ -13893,6 +14029,11 @@
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
"integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc="
},
"to-no-case": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz",
"integrity": "sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo="
},
"to-object-path": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
......@@ -13935,6 +14076,22 @@
}
}
},
"to-snake-case": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/to-snake-case/-/to-snake-case-1.0.0.tgz",
"integrity": "sha1-znRpE4l5RgGah+Yu366upMYIq4w=",
"requires": {
"to-space-case": "1.0.0"
}
},
"to-space-case": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz",
"integrity": "sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc=",
"requires": {
"to-no-case": "1.0.2"
}
},
"toggle-selection": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
......@@ -14356,6 +14513,15 @@
}
}
},
"url-parse": {
"version": "1.4.7",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz",
"integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==",
"requires": {
"querystringify": "2.1.1",
"requires-port": "1.0.0"
}
},
"url-toolkit": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/url-toolkit/-/url-toolkit-2.1.4.tgz",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment