diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index e50560a619f..234e9d1da10 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -14,6 +14,11 @@ Change Log
Unreleased
~~~~~~~~~~
+[3.19.0] - 2021-07-16
+~~~~~~~~~~~~~~~~~~~~~
+* Updated allowance modal to allow bulk allowances to be added.
+* Added waffle flag to enable/disable bulk allowances feature.
+
[3.18.0] - 2021-07-15
~~~~~~~~~~~~~~~~~~~~~
* Remove old proctored exam attempt url.
diff --git a/edx_proctoring/__init__.py b/edx_proctoring/__init__.py
index 93aebd9dc21..9856164995c 100644
--- a/edx_proctoring/__init__.py
+++ b/edx_proctoring/__init__.py
@@ -3,6 +3,6 @@
"""
# Be sure to update the version number in edx_proctoring/package.json
-__version__ = '3.18.0'
+__version__ = '3.19.0'
default_app_config = 'edx_proctoring.apps.EdxProctoringConfig' # pylint: disable=invalid-name
diff --git a/edx_proctoring/api.py b/edx_proctoring/api.py
index 49621f03728..2693de0736c 100644
--- a/edx_proctoring/api.py
+++ b/edx_proctoring/api.py
@@ -542,6 +542,8 @@ def add_bulk_allowances(exam_ids, user_ids, allowance_type, value):
"""
Adds (or updates) an allowance for multiple users and exams
"""
+
+ # Input pasrsing
exam_ids = set(exam_ids)
user_ids = set(user_ids)
@@ -569,7 +571,7 @@ def add_bulk_allowances(exam_ids, user_ids, allowance_type, value):
if multiplier < 0:
raise AllowanceValueNotAllowedException(err_msg)
- if allowance_type == constants.ADDITIONAL_TIME:
+ if allowance_type in ProctoredExamStudentAllowance.ADDITIONAL_TIME_GRANTED:
err_msg = (
u'allowance_value "{value}" should be a non-negative integer value'
).format(value=value)
@@ -631,7 +633,7 @@ def add_bulk_allowances(exam_ids, user_ids, allowance_type, value):
for user_id in user_ids:
try:
add_allowance_for_user(exam_id, user_id,
- ProctoredExamStudentAllowance.ADDITIONAL_TIME_GRANTED,
+ allowance_type,
value)
successes += 1
data.append({
diff --git a/edx_proctoring/constants.py b/edx_proctoring/constants.py
index 3396b2d9c8e..cec9c49d042 100644
--- a/edx_proctoring/constants.py
+++ b/edx_proctoring/constants.py
@@ -75,5 +75,3 @@
CONTENT_VIEWABLE_PAST_DUE_DATE = getattr(settings, 'PROCTORED_EXAM_VIEWABLE_PAST_DUE', False)
TIME_MULTIPLIER = 'time_multiplier'
-
-ADDITIONAL_TIME = 'additional_time'
diff --git a/edx_proctoring/settings/common.py b/edx_proctoring/settings/common.py
index b04e79fef77..80841654025 100644
--- a/edx_proctoring/settings/common.py
+++ b/edx_proctoring/settings/common.py
@@ -16,6 +16,7 @@ def plugin_settings(settings):
[
'proctoring/js/models/proctored_exam_allowance_model.js',
'proctoring/js/models/proctored_exam_attempt_model.js',
+ 'proctoring/js/models/proctored_exam_bulk_allowance_model.js',
'proctoring/js/models/proctored_exam_model.js',
'proctoring/js/models/learner_onboarding_model.js',
'proctoring/js/collections/proctored_exam_allowance_collection.js',
@@ -24,6 +25,7 @@ def plugin_settings(settings):
'proctoring/js/collections/proctored_exam_collection.js',
'proctoring/js/views/Backbone.ModalDialog.js',
'proctoring/js/views/proctored_exam_add_allowance_view.js',
+ 'proctoring/js/views/proctored_exam_add_bulk_allowance_view.js',
'proctoring/js/views/proctored_exam_allowance_view.js',
'proctoring/js/views/proctored_exam_attempt_view.js',
'proctoring/js/views/proctored_exam_onboarding_view.js',
diff --git a/edx_proctoring/static/proctoring/js/models/proctored_exam_bulk_allowance_model.js b/edx_proctoring/static/proctoring/js/models/proctored_exam_bulk_allowance_model.js
new file mode 100644
index 00000000000..dffb201ef9c
--- /dev/null
+++ b/edx_proctoring/static/proctoring/js/models/proctored_exam_bulk_allowance_model.js
@@ -0,0 +1,15 @@
+edx = edx || {};
+
+(function(Backbone) {
+ 'use strict';
+
+ edx.instructor_dashboard = edx.instructor_dashboard || {};
+ edx.instructor_dashboard.proctoring = edx.instructor_dashboard.proctoring || {};
+
+ edx.instructor_dashboard.proctoring.ProctoredExamBulkAllowanceModel = Backbone.Model.extend({
+ url: '/api/edx_proctoring/v1/proctored_exam/bulk_allowance'
+
+ });
+ this.edx.instructor_dashboard.proctoring.ProctoredExamBulkAllowanceModel =
+ edx.instructor_dashboard.proctoring.ProctoredExamBulkAllowanceModel;
+}).call(this, Backbone);
diff --git a/edx_proctoring/static/proctoring/js/views/proctored_exam_add_bulk_allowance_view.js b/edx_proctoring/static/proctoring/js/views/proctored_exam_add_bulk_allowance_view.js
new file mode 100644
index 00000000000..cdd6daf52c8
--- /dev/null
+++ b/edx_proctoring/static/proctoring/js/views/proctored_exam_add_bulk_allowance_view.js
@@ -0,0 +1,295 @@
+edx = edx || {};
+
+(function(Backbone, $, _, gettext) {
+ 'use strict';
+
+ edx.instructor_dashboard = edx.instructor_dashboard || {};
+ edx.instructor_dashboard.proctoring = edx.instructor_dashboard.proctoring || {};
+
+ edx.instructor_dashboard.proctoring.AddBulkAllowanceView = Backbone.ModalView.extend({
+ name: 'AddBulkAllowanceView',
+ template: null,
+ template_url: '/static/proctoring/templates/add-new-bulk-allowance.underscore',
+ initialize: function(options) {
+ this.all_exams = options.proctored_exams;
+ this.proctored_exams = [];
+ this.timed_exams = [];
+ this.proctored_exam_allowance_view = options.proctored_exam_allowance_view;
+ this.course_id = options.course_id;
+ this.allowance_types = options.allowance_types;
+ this.model = new edx.instructor_dashboard.proctoring.ProctoredExamBulkAllowanceModel();
+ _.bindAll(this, 'render');
+ this.loadTemplateData();
+ // Backbone.Validation.bind( this, {valid:this.hideError, invalid:this.showError});
+ },
+ events: {
+ 'submit form': 'addAllowance',
+ 'change #proctored_exam': 'selectExam',
+ 'change #timed_exam': 'selectExam',
+ 'change #allowance_type': 'selectAllowance',
+ 'change #exam_type': 'selectExamType'
+ },
+ loadTemplateData: function() {
+ var self = this;
+ $.ajax({url: self.template_url, dataType: 'html'})
+ .done(function(templateData) {
+ self.sortExamsByExamType();
+ self.template = _.template(templateData);
+ self.render();
+ self.showModal();
+ self.updateCss();
+ });
+ },
+ updateCss: function() {
+ var $el = $(this.el);
+ $el.find('.modal-header').css({
+ color: '#1580b0',
+ 'font-size': '20px',
+ 'font-weight': '600',
+ 'line-height': 'normal',
+ padding: '10px 15px',
+ 'border-bottom': '1px solid #ccc'
+ });
+ $el.find('form').css({
+ padding: '15px'
+ });
+ $el.find('form table.compact td').css({
+ 'vertical-align': 'middle',
+ padding: '4px 8px'
+ });
+ $el.find('form label').css({
+ display: 'block',
+ 'font-size': '14px',
+ margin: 0,
+ cursor: 'default'
+ });
+ $el.find('form #minutes_label').css({
+ display: 'inline-block'
+ });
+ $el.find('form input[type="text"]').css({
+ height: '26px',
+ padding: '1px 8px 2px',
+ 'font-size': '14px',
+ width: '100%'
+ });
+ $el.find('form input[type="submit"]').css({
+ 'margin-top': '10px',
+ float: 'right'
+ });
+ $el.find('.error-message').css({
+ color: '#ff0000',
+ 'line-height': 'normal',
+ 'font-size': '14px'
+ });
+ $el.find('.error-response').css({
+ color: '#ff0000',
+ 'line-height': 'normal',
+ 'font-size': '14px',
+ padding: '0px 10px 5px 7px'
+ });
+ $el.find('form select').css({
+ padding: '2px 0px 2px 2px',
+ 'font-size': '16px',
+ width: '100%'
+ });
+ $el.find('#selected_exams').css({
+ background: '#fff',
+ display: 'flex',
+ 'flex-wrap': 'wrap',
+ 'align-content': 'flex-start',
+ 'overflow-x': 'scroll'
+ });
+ $el.find('.tag').css({
+ 'font-size': '14px',
+ height: '15px',
+ 'margin-right': '5px',
+ padding: '5px 6px',
+ border: '1px solid #ccc',
+ 'border-radius': '3px',
+ background: '#eee',
+ display: 'flex',
+ 'align-items': 'center',
+ color: '#333',
+ 'box-shadow': '0 0 4px rgba(0, 0, 0, 0.2), inset 0 1px 1px #fff',
+ cursor: 'default'
+ });
+ $el.find('.close').css({
+ 'font-size': '16px',
+ margin: '5px'
+ });
+ $el.find('.exam_dropdown').css({
+ height: '60px'
+ });
+ },
+ getCurrentFormValues: function() {
+ return {
+ proctored_exam: this.selectedExams,
+ allowance_type: $('select#allowance_type').val(),
+ allowance_value: $('#allowance_value').val(),
+ user_info: $('#user_info').val()
+ };
+ },
+ hideError: function(view, attr) {
+ var $element = view.$form[attr];
+
+ $element.removeClass('error');
+ $element.parent().find('.error-message').empty();
+ },
+ showError: function(view, attr, errorMessage) {
+ var $element = view.$form[attr];
+ var $errorMessage;
+
+ $element.addClass('error');
+ $errorMessage = $element.parent().find('.error-message');
+ if ($errorMessage.length === 0) {
+ $errorMessage = $("
");
+ $element.parent().append($errorMessage);
+ }
+
+ $errorMessage.empty().append(errorMessage);
+ this.updateCss();
+ },
+ addAllowance: function(event) {
+ var $errorResponse, values, formHasErrors, exams;
+ var self = this;
+ event.preventDefault();
+ $errorResponse = $('.error-response');
+ $errorResponse.html();
+ values = this.getCurrentFormValues();
+ formHasErrors = false;
+ exams = '';
+
+ $('.close').each(function() {
+ exams += $(this).attr('data-item') + ',';
+ });
+
+ $.each(values, function(key, value) {
+ if (value === '') {
+ formHasErrors = true;
+ self.showError(self, key, gettext('Required field'));
+ } else {
+ self.hideError(self, key);
+ }
+ });
+
+ if (exams === '') {
+ formHasErrors = true;
+ self.showError(self, 'proctored_exam', gettext('Required field'));
+ } else {
+ self.hideError(self, 'proctored_exam');
+ }
+
+ if (!formHasErrors) {
+ self.model.fetch({
+ headers: {
+ 'X-CSRFToken': self.proctored_exam_allowance_view.getCSRFToken()
+ },
+ type: 'PUT',
+ data: {
+ exam_ids: exams,
+ user_ids: values.user_info,
+ allowance_type: values.allowance_type,
+ value: values.allowance_value
+ },
+ success: function() {
+ // fetch the allowances again.
+ $errorResponse.html();
+ self.proctored_exam_allowance_view.collection.url =
+ self.proctored_exam_allowance_view.initial_url + self.course_id + '/allowance';
+ self.proctored_exam_allowance_view.hydrate();
+ self.hideModal();
+ },
+ error: function(unused, response) {
+ var data = $.parseJSON(response.responseText);
+ $errorResponse.html(gettext(data.detail));
+ }
+ });
+ }
+ },
+ selectExamAtIndex: function(examID, examName) {
+ var createdTag = this.createTag(examName, examID);
+ $('.exam_dropdown:visible').val('default');
+ $('.exam_dropdown:visible option[value=' + examID + ']').remove();
+ $('#selected_exams').append(createdTag);
+ this.updateCss();
+ },
+ selectExam: function() {
+ this.selectExamAtIndex($('.exam_dropdown:visible').val(), $('.exam_dropdown:visible :selected').text());
+ },
+ selectAllowance: function() {
+ this.updateAllowanceLabels($('#allowance_type').val());
+ },
+ selectExamType: function() {
+ $('.close').each(function() {
+ $(this).trigger('click');
+ });
+ if ($('#proctored_exam').is(':visible')) {
+ $('#proctored_exam').hide();
+ $('#timed_exam').show();
+ $('#allowance_type option[value="review_policy_exception"]').remove();
+ } else {
+ $('#proctored_exam').show();
+ $('#timed_exam').hide();
+ $('#allowance_type').append(new Option(gettext('Review Policy Exception'), 'review_policy_exception'));
+ }
+ this.updateAllowanceLabels($('#allowance_type').val());
+ },
+ updateAllowanceLabels: function(selectedAllowanceType) {
+ if (selectedAllowanceType === 'additional_time_granted') {
+ $('#allowance_value_label').text(gettext('Input Additional Minutes as a Positive Number'));
+ } else if (selectedAllowanceType === 'time_multiplier') {
+ $('#allowance_value_label').text(gettext('Input Multiplier as a Number Greater Than 1'));
+ } else {
+ $('#allowance_value_label').text(gettext('Add Policy Exception'));
+ }
+ },
+ sortExamsByExamType: function() {
+ var self = this;
+ self.all_exams.forEach(function(exam) {
+ if (exam.is_proctored) {
+ self.proctored_exams.push(exam);
+ } else {
+ self.timed_exams.push(exam);
+ }
+ });
+ },
+ createTag: function(examName, examID) {
+ var div = document.createElement('div');
+ var span = document.createElement('span');
+ var closeIcon = document.createElement('span');
+ div.setAttribute('class', 'tag');
+ span.innerHTML = examName;
+ closeIcon.innerHTML = 'x';
+ closeIcon.setAttribute('class', 'close');
+ closeIcon.setAttribute('data-item', examID);
+ closeIcon.setAttribute('data-name', examName);
+ closeIcon.onclick = this.deleteTag;
+ div.appendChild(span);
+ div.appendChild(closeIcon);
+ return div;
+ },
+ deleteTag: function() {
+ var examID = $(this).data('item');
+ var examName = $(this).data('name');
+ $(this).closest('div').remove();
+ $('.exam_dropdown:visible').append(new Option(examName, examID));
+ },
+
+ render: function() {
+ $(this.el).html(this.template({
+ proctored_exams: this.proctored_exams,
+ timed_exams: this.timed_exams,
+ allowance_types: this.allowance_types
+ }));
+
+ this.$form = {
+ proctored_exam: this.$('select#proctored_exam'),
+ timed_exam: this.$('select#timed_exam'),
+ allowance_type: this.$('select#allowance_type'),
+ allowance_value: this.$('#allowance_value'),
+ user_info: this.$('#user_info')
+ };
+ return this;
+ }
+ });
+}).call(this, Backbone, $, _, gettext);
diff --git a/edx_proctoring/static/proctoring/js/views/proctored_exam_allowance_view.js b/edx_proctoring/static/proctoring/js/views/proctored_exam_allowance_view.js
index a05510f2b37..fd53dd045c6 100644
--- a/edx_proctoring/static/proctoring/js/views/proctored_exam_allowance_view.js
+++ b/edx_proctoring/static/proctoring/js/views/proctored_exam_allowance_view.js
@@ -10,7 +10,8 @@ edx = edx || {};
initialize: function() {
this.allowance_types = [
['additional_time_granted', gettext('Additional Time (minutes)')],
- ['review_policy_exception', gettext('Review Policy Exception')]
+ ['review_policy_exception', gettext('Review Policy Exception')],
+ ['time_multiplier', gettext('Time Multiplier')]
];
this.collection = new edx.instructor_dashboard.proctoring.ProctoredExamAllowanceCollection();
@@ -143,15 +144,29 @@ edx = edx || {};
},
showAddModal: function(event) {
var self = this;
+ var enableBulkAllowance =
+ self.$el.data('enable-bulk-allowance');
+ enableBulkAllowance = enableBulkAllowance &&
+ enableBulkAllowance.toLowerCase() === 'true';
self.proctoredExamCollection.fetch({
success: function() {
- // eslint-disable-next-line no-new
- new edx.instructor_dashboard.proctoring.AddAllowanceView({
- course_id: self.course_id,
- proctored_exams: self.proctoredExamCollection.toJSON(),
- proctored_exam_allowance_view: self,
- allowance_types: self.allowance_types
- });
+ if (!enableBulkAllowance) {
+ // eslint-disable-next-line no-new
+ new edx.instructor_dashboard.proctoring.AddAllowanceView({
+ course_id: self.course_id,
+ proctored_exams: self.proctoredExamCollection.toJSON(),
+ proctored_exam_allowance_view: self,
+ allowance_types: self.allowance_types
+ });
+ } else {
+ // eslint-disable-next-line no-new
+ new edx.instructor_dashboard.proctoring.AddBulkAllowanceView({
+ course_id: self.course_id,
+ proctored_exams: self.proctoredExamCollection.toJSON(),
+ proctored_exam_allowance_view: self,
+ allowance_types: self.allowance_types
+ });
+ }
}
});
event.stopPropagation();
diff --git a/edx_proctoring/static/proctoring/spec/proctored_exam_add_bulk_allowance_spec.js b/edx_proctoring/static/proctoring/spec/proctored_exam_add_bulk_allowance_spec.js
new file mode 100644
index 00000000000..ab51a804140
--- /dev/null
+++ b/edx_proctoring/static/proctoring/spec/proctored_exam_add_bulk_allowance_spec.js
@@ -0,0 +1,337 @@
+describe('ProctoredExamAAllowanceView', function() {
+ 'use strict';
+
+ var html = '';
+ var allowancesHtml = '';
+ var errorAddingAllowance = {
+ detail: 'Cannot find user'
+ };
+ var expectedProctoredAllowanceJson = [
+ {
+ created: '2015-08-10T09:15:45Z',
+ id: 1,
+ modified: '2015-08-10T09:15:45Z',
+ key: 'additional_time_granted',
+ value: '1',
+ proctored_exam: {
+ content_id: 'i4x://edX/DemoX/sequential/9f5e9b018a244ea38e5d157e0019e60c',
+ course_id: 'edX/DemoX/Demo_Course',
+ exam_name: 'Test Exam',
+ external_id: null,
+ id: 6,
+ is_active: true,
+ is_practice_exam: false,
+ is_proctored: true,
+ time_limit_mins: 1
+ },
+ user: {
+ username: 'testuser1',
+ email: 'testuser1@test.com'
+ }
+ }
+ ];
+
+ var expectedTimedAllowanceJson = [
+ {
+ created: '2015-08-10T09:15:45Z',
+ id: 1,
+ modified: '2015-08-10T09:15:45Z',
+ key: 'additional_time_granted',
+ value: '1',
+ proctored_exam: {
+ content_id: 'i4x://edX/DemoX/sequential/9f5e9b018a244ea38e5d157e0019e60c',
+ course_id: 'edX/DemoX/Demo_Course',
+ exam_name: 'Test Exam',
+ external_id: null,
+ id: 6,
+ is_active: true,
+ is_practice_exam: false,
+ is_proctored: false,
+ time_limit_mins: 1
+ },
+ user: {
+ username: 'testuser1',
+ email: 'testuser1@test.com'
+ }
+ }
+ ];
+
+ var proctoredExamJson = [
+ {
+ exam_name: 'Midterm Exam',
+ is_proctored: true,
+ is_practice: false,
+ id: 5
+ },
+ {
+ exam_name: 'Final Exam',
+ is_proctored: false,
+ is_practice: false,
+ id: 6
+ },
+ {
+ exam_name: 'Test Exam',
+ is_proctored: true,
+ is_practice: true,
+ id: 7
+ }
+ ];
+
+ var allowanceTypes = [
+ ['additional_time_granted', gettext('Additional Time (minutes)')],
+ ['review_policy_exception', gettext('Review Policy Exception')],
+ ['time_multiplier', gettext('Time Multiplier')]
+ ];
+
+ beforeEach(function() {
+ // We have converted the edx_proctoring/static/proctoring/templates/add-new-allowance.underscore template
+ // from http://www.howtocreate.co.uk/tutorials/jsexamples/syntax/prepareInline.html
+
+ // eslint-disable-next-line max-len
+ html = '\n';
+
+ allowancesHtml = '' +
+ '<%- gettext("Allowances") %>' +
+ ' +' +
+ '<%- gettext("Add Allowance") %>' +
+ ' ' +
+ '<% var is_allowances = proctored_exam_allowances.length !== 0 %>' +
+ '<% if (is_allowances) { %>' +
+ ' ' +
+ '' +
+ 'Exam Name | ' +
+ 'Username | ' +
+ 'Email | ' +
+ 'Allowance Type | ' +
+ 'Allowance Value | ' +
+ 'Actions | ' +
+ '
' +
+ '' +
+ '<% _.each(proctored_exam_allowances, function(proctored_exam_allowance){ %>' +
+ '' +
+ '' +
+ '<%- interpolate(gettext(" %(exam_display_name)s "),' +
+ '{ exam_display_name: proctored_exam_allowance.proctored_exam.exam_name }, true) %>' +
+ ' | ' +
+ '<% if (proctored_exam_allowance.user){ %>' +
+ '' +
+ '<%- interpolate(gettext(" %(username)s "),' +
+ '{ username: proctored_exam_allowance.user.username }, true) %>' +
+ ' | ' +
+ '' +
+ '<%- interpolate(gettext(" %(email)s "),' +
+ '{ email: proctored_exam_allowance.user.email }, true) %>' +
+ ' | ' +
+ '<% }else{ %>' +
+ 'N/A | N/A | ' +
+ '<% } %>' +
+ '' +
+ '<%- interpolate(gettext(" %(allowance_name)s "),' +
+ '{ allowance_name: proctored_exam_allowance.key_display_name }, true) %>' +
+ ' | ' +
+ '' +
+ '<%= proctored_exam_allowance.value %>' +
+ ' | ' +
+ '' +
+ '" ' +
+ 'data-user-id="<%= proctored_exam_allowance.user.id %>"class="remove_allowance" href="#">[x]' +
+ ' |
' +
+ '<% }); %>' +
+ '
' +
+ '<% } %>';
+ this.server = sinon.fakeServer.create();
+ this.server.autoRespond = true;
+
+ setFixtures('');
+ // load the underscore template response before calling the proctored exam allowance view.
+ this.server.respondWith('GET', '/static/proctoring/templates/add-new-bulk-allowance.underscore',
+ [
+ 200,
+ {'Content-Type': 'text/html'},
+ html
+ ]
+ );
+ this.server.respondWith('GET', '/static/proctoring/templates/course_allowances.underscore',
+ [
+ 200,
+ {'Content-Type': 'text/html'},
+ allowancesHtml
+ ]
+ );
+ });
+
+ afterEach(function() {
+ this.server.restore();
+ });
+ it('should render the proctored exam add allowance view properly', function() {
+ var addAllowanceView;
+ this.server.respondWith('GET', '/api/edx_proctoring/v1/proctored_exam/test_course_id/allowance',
+ [
+ 200,
+ {
+ 'Content-Type': 'application/json'
+ },
+ JSON.stringify(expectedProctoredAllowanceJson)
+ ]
+ );
+
+ this.proctored_exam_allowance = new edx.instructor_dashboard.proctoring.ProctoredExamAllowanceView();
+ addAllowanceView = new edx.instructor_dashboard.proctoring.AddBulkAllowanceView({
+ course_id: 'test_course_id',
+ proctored_exams: proctoredExamJson,
+ proctored_exam_allowance_view: this.proctored_exam_allowance,
+ allowance_types: allowanceTypes
+ });
+ this.server.respond();
+ this.server.respond();
+ this.server.respond();
+
+ expect(addAllowanceView.$el.find('#proctored_exam').html()).toContain('Midterm Exam');
+ expect(addAllowanceView.$el.find('#proctored_exam').html()).toContain('Test Exam');
+ $('#proctored_exam').val('5');
+ });
+
+
+ it('should render the timed exam add allowance view properly', function() {
+ var addAllowanceView;
+ this.server.respondWith('GET', '/api/edx_proctoring/v1/proctored_exam/test_course_id/allowance',
+ [
+ 200,
+ {
+ 'Content-Type': 'application/json'
+ },
+ JSON.stringify(expectedTimedAllowanceJson)
+ ]
+ );
+
+ this.proctored_exam_allowance = new edx.instructor_dashboard.proctoring.ProctoredExamAllowanceView();
+ addAllowanceView = new edx.instructor_dashboard.proctoring.AddBulkAllowanceView({
+ course_id: 'test_course_id',
+ proctored_exams: proctoredExamJson,
+ proctored_exam_allowance_view: this.proctored_exam_allowance,
+ allowance_types: allowanceTypes
+ });
+ this.server.respond();
+ this.server.respond();
+ this.server.respond();
+
+ expect(addAllowanceView.$el.find('#timed_exam').html()).toContain('Final Exam');
+ $('#timed_exam').val('6');
+ });
+
+
+ it('should add the proctored exam allowance', function() {
+ this.server.respondWith('GET', '/api/edx_proctoring/v1/proctored_exam/test_course_id/allowance',
+ [
+ 200,
+ {
+ 'Content-Type': 'application/json'
+ },
+ JSON.stringify([])
+ ]
+ );
+
+ this.proctored_exam_allowance = new edx.instructor_dashboard.proctoring.ProctoredExamAllowanceView();
+ // eslint-disable-next-line no-new
+ new edx.instructor_dashboard.proctoring.AddBulkAllowanceView({
+ course_id: 'test_course_id',
+ proctored_exams: proctoredExamJson,
+ proctored_exam_allowance_view: this.proctored_exam_allowance,
+ allowance_types: allowanceTypes
+ });
+
+ this.server.respond();
+ this.server.respond();
+ this.server.respond();
+
+ expect(this.proctored_exam_allowance.$el.find('tr.allowance-items').html())
+ .not.toContain('testuser1');
+ expect(this.proctored_exam_allowance.$el.find('tr.allowance-items').html())
+ .not.toContain('testuser1@test.com');
+ expect(this.proctored_exam_allowance.$el.find('tr.allowance-items').html())
+ .not.toContain('Additional Time (minutes)');
+ expect(this.proctored_exam_allowance.$el.find('tr.allowance-items').html())
+ .not.toContain('Test Exam');
+
+ // add the proctored exam allowance
+ this.server.respondWith('PUT', '/api/edx_proctoring/v1/proctored_exam/bulk_allowance',
+ [
+ 200,
+ {
+ 'Content-Type': 'application/json'
+ },
+ JSON.stringify([])
+ ]
+ );
+ });
+ it('should send error when adding proctored exam allowance', function() {
+ var addAllowanceView;
+ this.server.respondWith('GET', '/api/edx_proctoring/v1/proctored_exam/test_course_id/allowance',
+ [
+ 200,
+ {
+ 'Content-Type': 'application/json'
+ },
+ JSON.stringify([])
+ ]
+ );
+
+ this.proctored_exam_allowance = new edx.instructor_dashboard.proctoring.ProctoredExamAllowanceView();
+ addAllowanceView = new edx.instructor_dashboard.proctoring.AddBulkAllowanceView({
+ course_id: 'test_course_id',
+ proctored_exams: proctoredExamJson,
+ proctored_exam_allowance_view: this.proctored_exam_allowance,
+ allowance_types: allowanceTypes
+ });
+
+ this.server.respond();
+ this.server.respond();
+ this.server.respond();
+
+ expect(this.proctored_exam_allowance.$el.find('tr.allowance-items').html())
+ .not.toContain('testuser1');
+ expect(this.proctored_exam_allowance.$el.find('tr.allowance-items').html())
+ .not.toContain('testuser1@test.com');
+ expect(this.proctored_exam_allowance.$el.find('tr.allowance-items').html())
+ .not.toContain('Additional Time (minutes)');
+ expect(this.proctored_exam_allowance.$el.find('tr.allowance-items').html())
+ .not.toContain('Test Exam');
+
+ // add the proctored exam allowance
+ this.server.respondWith('PUT', '/api/edx_proctoring/v1/proctored_exam/bulk_allowance',
+ [
+ 400,
+ {
+ 'Content-Type': 'application/json'
+ },
+ JSON.stringify(errorAddingAllowance)
+ ]
+ );
+
+ // again fetch the results after the proctored exam allowance addition
+ this.server.respondWith('GET', '/api/edx_proctoring/v1/proctored_exam/test_course_id/allowance',
+ [
+ 200,
+ {
+ 'Content-Type': 'application/json'
+ },
+ JSON.stringify(expectedProctoredAllowanceJson)
+ ]
+ );
+
+ // select the form values
+ // empty value returns error
+ $('#proctored_exam').val('Test Exam');
+ $('#allowance_type').val('Additional Time (minutes)');
+ $('#allowance_value').val('');
+ $('#user_info').val('testuser1');
+
+ // trigger the add allowance event.
+ spyOnEvent('form', 'submit');
+ $('form').trigger('submit');
+
+ expect(addAllowanceView.$el.find('.error-message').html()).toContain('Required field');
+ });
+});
diff --git a/edx_proctoring/static/proctoring/templates/add-new-bulk-allowance.underscore b/edx_proctoring/static/proctoring/templates/add-new-bulk-allowance.underscore
new file mode 100644
index 00000000000..74dbb238c83
--- /dev/null
+++ b/edx_proctoring/static/proctoring/templates/add-new-bulk-allowance.underscore
@@ -0,0 +1,105 @@
+
+
+
diff --git a/edx_proctoring/tests/test_api.py b/edx_proctoring/tests/test_api.py
index dc42e3363e3..f4604f05c3e 100644
--- a/edx_proctoring/tests/test_api.py
+++ b/edx_proctoring/tests/test_api.py
@@ -65,7 +65,7 @@
update_review_policy
)
from edx_proctoring.backends.tests.test_backend import TestBackendProvider
-from edx_proctoring.constants import ADDITIONAL_TIME, DEFAULT_CONTACT_EMAIL, TIME_MULTIPLIER
+from edx_proctoring.constants import DEFAULT_CONTACT_EMAIL, TIME_MULTIPLIER
from edx_proctoring.exceptions import (
AllowanceValueNotAllowedException,
BackendProviderSentNoAttemptID,
@@ -502,7 +502,7 @@ def test_remove_allowance_for_user(self):
@ddt.data(
(
- ADDITIONAL_TIME,
+ ProctoredExamStudentAllowance.ADDITIONAL_TIME_GRANTED,
'30',
'30',
'30'
@@ -629,7 +629,7 @@ def test_add_same_exam_bulk_allowance(self):
@ddt.data(
(
- ADDITIONAL_TIME,
+ ProctoredExamStudentAllowance.ADDITIONAL_TIME_GRANTED[0],
'30',
'30',
'30'
@@ -684,7 +684,7 @@ def test_add_bulk_allowance_invalid_user(self, allowance_type, value, exam1_allo
@ddt.data(
(
- ADDITIONAL_TIME,
+ ProctoredExamStudentAllowance.ADDITIONAL_TIME_GRANTED[0],
'30',
'30',
'30'
@@ -739,19 +739,19 @@ def test_add_bulk_allowance_invalid_exam(self, allowance_type, value, exam1_allo
@ddt.data(
(
- ADDITIONAL_TIME,
+ ProctoredExamStudentAllowance.ADDITIONAL_TIME_GRANTED[0],
'3.0'
),
(
- ADDITIONAL_TIME,
+ ProctoredExamStudentAllowance.ADDITIONAL_TIME_GRANTED[0],
'invalid'
),
(
- ADDITIONAL_TIME,
+ ProctoredExamStudentAllowance.ADDITIONAL_TIME_GRANTED[0],
'-30'
),
(
- ADDITIONAL_TIME,
+ ProctoredExamStudentAllowance.ADDITIONAL_TIME_GRANTED[0],
'd30'
),
(
diff --git a/edx_proctoring/tests/test_views.py b/edx_proctoring/tests/test_views.py
index 47f6bc0beba..457c7567af5 100644
--- a/edx_proctoring/tests/test_views.py
+++ b/edx_proctoring/tests/test_views.py
@@ -32,7 +32,7 @@
from edx_proctoring.backends.tests.test_backend import TestBackendProvider
from edx_proctoring.backends.tests.test_review_payload import create_test_review_payload
from edx_proctoring.backends.tests.test_software_secure import mock_response_content
-from edx_proctoring.constants import ADDITIONAL_TIME, TIME_MULTIPLIER
+from edx_proctoring.constants import TIME_MULTIPLIER
from edx_proctoring.exceptions import (
BackendProviderOnboardingProfilesException,
ProctoredExamIllegalStatusTransition,
@@ -4910,12 +4910,20 @@ def setUp(self):
@ddt.data(
(
- ADDITIONAL_TIME,
+ 'additional_time_granted',
'30'
),
(
TIME_MULTIPLIER,
'1.5'
+ ),
+ (
+ 'review_policy_exception',
+ 'notes'
+ ),
+ (
+ 'review_policy_exception',
+ 25
)
)
@ddt.unpack
@@ -4943,8 +4951,8 @@ def test_add_bulk_time_allowances(self, allowance_type, value):
exam_list = [exam1.id, exam2.id]
allowance_data = {
- 'exam_ids': exam_list,
- 'user_ids': user_id_list,
+ 'exam_ids': ','.join(str(exam) for exam in exam_list),
+ 'user_ids': ','.join(str(user) for user in user_id_list),
'allowance_type': allowance_type,
'value': value
}
@@ -4983,9 +4991,9 @@ def test_add_bulk_allowance_non_staff_user(self): # pylint: disable=invalid-nam
exam_list = [exam1.id, exam2.id]
allowance_data = {
- 'exam_ids': exam_list,
- 'user_ids': user_id_list,
- 'allowance_type': ADDITIONAL_TIME,
+ 'exam_ids': ','.join(str(exam) for exam in exam_list),
+ 'user_ids': ','.join(str(user) for user in user_id_list),
+ 'allowance_type': 'additional_time_granted',
'value': '30'
}
response = self.client.put(
@@ -4999,12 +5007,20 @@ def test_add_bulk_allowance_non_staff_user(self): # pylint: disable=invalid-nam
@ddt.data(
(
- ADDITIONAL_TIME,
+ 'additional_time_granted',
'30'
),
(
TIME_MULTIPLIER,
'1.5'
+ ),
+ (
+ 'review_policy_exception',
+ 'notes'
+ ),
+ (
+ 'review_policy_exception',
+ 25
)
)
@ddt.unpack
@@ -5033,8 +5049,9 @@ def test_add_bulk_allowance_invalid_user(self, allowance_type, value): # pylint
exam_list = [exam1.id, exam2.id]
allowance_data = {
- 'exam_ids': exam_list,
- 'user_ids': user_id_list,
+ 'exam_ids': ','.join(str(exam) for exam in exam_list),
+ # Add additonal whitesapce for invalid users
+ 'user_ids': ','.join(str(user) for user in user_id_list) + ',, , ,w',
'allowance_type': allowance_type,
'value': value
}
@@ -5047,12 +5064,20 @@ def test_add_bulk_allowance_invalid_user(self, allowance_type, value): # pylint
@ddt.data(
(
- ADDITIONAL_TIME,
+ 'additional_time_granted',
'30'
),
(
TIME_MULTIPLIER,
'1.5'
+ ),
+ (
+ 'review_policy_exception',
+ 'notes'
+ ),
+ (
+ 'review_policy_exception',
+ 25
)
)
@ddt.unpack
@@ -5080,8 +5105,9 @@ def test_add_bulk_allowance_invalid_exam(self, allowance_type, value): # pylint
exam_list = [exam1.id, exam2.id, -99]
allowance_data = {
- 'exam_ids': exam_list,
- 'user_ids': user_id_list,
+ # Test added whitesapce in the exam id input
+ 'exam_ids': ','.join(str(exam) for exam in exam_list) + ',2 3, 22,',
+ 'user_ids': ','.join(str(user) for user in user_id_list),
'allowance_type': allowance_type,
'value': value
}
@@ -5094,7 +5120,7 @@ def test_add_bulk_allowance_invalid_exam(self, allowance_type, value): # pylint
@ddt.data(
(
- ADDITIONAL_TIME,
+ 'additional_time_granted',
'-30'
),
(
@@ -5131,8 +5157,8 @@ def test_add_bulk_allowance_invalid_allowance_value(self, allowance_type, value)
exam_list = [exam1.id, exam2.id]
allowance_data = {
- 'exam_ids': exam_list,
- 'user_ids': user_id_list,
+ 'exam_ids': ','.join(str(exam) for exam in exam_list),
+ 'user_ids': ','.join(str(user) for user in user_id_list),
'allowance_type': allowance_type,
'value': value
}
@@ -5152,9 +5178,9 @@ def test_add_bulk_allowance_all_invalid_data(self): # pylint: disable=invalid-n
exam_list = [-99, -98]
allowance_data = {
- 'exam_ids': exam_list,
- 'user_ids': user_id_list,
- 'allowance_type': ADDITIONAL_TIME,
+ 'exam_ids': ','.join(str(exam) for exam in exam_list),
+ 'user_ids': ','.join(str(user) for user in user_id_list),
+ 'allowance_type': 'additional_time_granted',
'value': '30'
}
response = self.client.put(
@@ -5169,7 +5195,6 @@ def test_add_bulk_allowance_no_users(self): # pylint: disable=invalid-name
Test to add bulk allowance with no users
"""
# Create exams.
- user_id_list = []
exam1 = ProctoredExam.objects.create(
course_id='a/b/c',
content_id='test_content',
@@ -5187,9 +5212,9 @@ def test_add_bulk_allowance_no_users(self): # pylint: disable=invalid-name
exam_list = [exam1.id, exam2.id]
allowance_data = {
- 'exam_ids': exam_list,
- 'user_ids': user_id_list,
- 'allowance_type': ADDITIONAL_TIME,
+ 'exam_ids': ','.join(str(exam) for exam in exam_list),
+ 'user_ids': ' ',
+ 'allowance_type': 'additional_time_granted',
'value': '30'
}
response = self.client.put(
@@ -5206,12 +5231,11 @@ def test_add_bulk_allowance_no_exams(self): # pylint: disable=invalid-name
# Create exams.
user_list = self.create_batch_users(3)
user_id_list = [user.email for user in user_list]
- exam_list = []
allowance_data = {
- 'exam_ids': exam_list,
- 'user_ids': user_id_list,
- 'allowance_type': ADDITIONAL_TIME,
+ 'exam_ids': ' ',
+ 'user_ids': ','.join(str(user) for user in user_id_list),
+ 'allowance_type': 'additional_time_granted',
'value': '30'
}
response = self.client.put(
@@ -5253,9 +5277,9 @@ def test_get_grouped_allowances(self):
exam_list = [exam1.id]
allowance_data = {
- 'exam_ids': exam_list,
- 'user_ids': user_id_list,
- 'allowance_type': ADDITIONAL_TIME,
+ 'exam_ids': ','.join(str(exam) for exam in exam_list),
+ 'user_ids': ','.join(str(user) for user in user_id_list),
+ 'allowance_type': 'additional_time_granted',
'value': '30'
}
self.client.put(
@@ -5315,9 +5339,9 @@ def test_get_grouped_allowances_non_staff(self):
exam_list = [exam1.id, exam2.id]
allowance_data = {
- 'exam_ids': exam_list,
- 'user_ids': user_id_list,
- 'allowance_type': ADDITIONAL_TIME,
+ 'exam_ids': ','.join(str(exam) for exam in exam_list),
+ 'user_ids': ','.join(str(user) for user in user_id_list),
+ 'allowance_type': 'additional_time_granted',
'value': '30'
}
self.client.put(
@@ -5377,9 +5401,9 @@ def test_get_grouped_allowances_non_global_staff(self):
exam_list = [exam1.id, exam2.id]
allowance_data = {
- 'exam_ids': exam_list,
- 'user_ids': user_id_list,
- 'allowance_type': ADDITIONAL_TIME,
+ 'exam_ids': ','.join(str(exam) for exam in exam_list),
+ 'user_ids': ','.join(str(user) for user in user_id_list),
+ 'allowance_type': 'additional_time_granted',
'value': '30'
}
self.client.put(
diff --git a/edx_proctoring/views.py b/edx_proctoring/views.py
index 0e8e89da2bf..bd1086deafb 100644
--- a/edx_proctoring/views.py
+++ b/edx_proctoring/views.py
@@ -1544,16 +1544,23 @@ def put(self, request):
HTTP PUT handler. Adds or updates Allowances for many exams and students
"""
try:
+ exams = request.data.get('exam_ids', '')
+ users = request.data.get('user_ids', '')
+
+ # We need to remove whitespace from the exam ids as they are ints
+ filtered_ids = ''.join(exams.split())
+ filtered_users = ''.join(users.split())
data, successes, failures = add_bulk_allowances(
- exam_ids=request.data.get('exam_ids', None),
- user_ids=request.data.get('user_ids', None),
+ # We only want to pass ints that are not empty
+ exam_ids=[each_exam for each_exam in filtered_ids.split(',') if each_exam],
+ user_ids=[each_user.strip() for each_user in filtered_users.split(',') if each_user],
allowance_type=request.data.get('allowance_type', None),
value=request.data.get('value', None)
)
if successes == 0:
return Response(
status=status.HTTP_400_BAD_REQUEST,
- data=data
+ data={"detail": _("Enter a valid username or email")}
)
if failures > 0:
return Response(
@@ -1566,7 +1573,7 @@ def put(self, request):
except AllowanceValueNotAllowedException:
return Response(
status=status.HTTP_400_BAD_REQUEST,
- data={"detail": _("Must be a Staff User to Perform this request.")}
+ data={"detail": _("Enter a valid positive value number")}
)
diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json
index bff737cb4d5..8b58cc938cc 100644
--- a/npm-shrinkwrap.json
+++ b/npm-shrinkwrap.json
@@ -1,31 +1,31 @@
{
"name": "@edx/edx-proctoring",
- "version": "3.9.1",
+ "version": "3.17.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@babel/code-frame": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
- "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
"dev": true,
"requires": {
- "@babel/highlight": "^7.12.13"
+ "@babel/highlight": "^7.14.5"
}
},
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
},
"@babel/highlight": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz",
- "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"chalk": "^2.0.0",
"js-tokens": "^4.0.0"
}
@@ -77,12 +77,6 @@
"integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==",
"dev": true
},
- "@types/json5": {
- "version": "0.0.29",
- "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
- "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
- "dev": true
- },
"abbrev": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz",
@@ -114,9 +108,9 @@
"dev": true
},
"acorn-jsx": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz",
- "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==",
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"dev": true
},
"active-x-obfuscator": {
@@ -351,9 +345,9 @@
"dev": true
},
"array-filter": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz",
- "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=",
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz",
+ "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=",
"dev": true
},
"array-find-index": {
@@ -495,13 +489,10 @@
"dev": true
},
"available-typed-arrays": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz",
- "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==",
- "dev": true,
- "requires": {
- "array-filter": "^1.0.0"
- }
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz",
+ "integrity": "sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA==",
+ "dev": true
},
"aws-sign2": {
"version": "0.5.0",
@@ -737,16 +728,6 @@
"integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
"dev": true
},
- "bindings": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
- "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
- "dev": true,
- "optional": true,
- "requires": {
- "file-uri-to-path": "1.0.0"
- }
- },
"bl": {
"version": "0.9.5",
"resolved": "https://registry.npmjs.org/bl/-/bl-0.9.5.tgz",
@@ -1743,9 +1724,9 @@
}
},
"config-chain": {
- "version": "1.1.12",
- "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz",
- "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==",
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
+ "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
"dev": true,
"requires": {
"ini": "^1.3.4",
@@ -1807,16 +1788,6 @@
}
}
},
- "contains-path": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-1.0.0.tgz",
- "integrity": "sha1-NFizMhhWA+ju0Y9RjUoQiIo6vJE=",
- "dev": true,
- "requires": {
- "normalize-path": "^2.1.1",
- "path-starts-with": "^1.0.0"
- }
- },
"content-type": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
@@ -1941,9 +1912,9 @@
"dev": true
},
"debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"dev": true,
"requires": {
"ms": "2.1.2"
@@ -2325,9 +2296,9 @@
}
},
"engine.io-client": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.5.tgz",
- "integrity": "sha512-AYTgHyeVUPitsseqjoedjhYJapNVoSPShbZ+tEUX9/73jgZ/Z3sUlJf9oYgdEBBdVhupUpUqSxH0kBCXlQnmZg==",
+ "version": "1.8.6",
+ "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.6.tgz",
+ "integrity": "sha512-6+rInQu8xU7c0fIF6RC4SRKuHVWPt8Xq0bZYS4lMrTwmhRineOlEMsU3X0zS5mHIvCgJsmpOKEX7DhihGk7j0g==",
"dev": true,
"requires": {
"component-emitter": "1.2.1",
@@ -2340,7 +2311,7 @@
"parseqs": "0.0.5",
"parseuri": "0.0.5",
"ws": "~1.1.5",
- "xmlhttprequest-ssl": "1.5.3",
+ "xmlhttprequest-ssl": "1.6.3",
"yeast": "0.1.2"
},
"dependencies": {
@@ -2407,9 +2378,9 @@
}
},
"es-abstract": {
- "version": "1.18.0",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz",
- "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==",
+ "version": "1.18.3",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz",
+ "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==",
"dev": true,
"requires": {
"call-bind": "^1.0.2",
@@ -2420,14 +2391,14 @@
"has-symbols": "^1.0.2",
"is-callable": "^1.2.3",
"is-negative-zero": "^2.0.1",
- "is-regex": "^1.1.2",
- "is-string": "^1.0.5",
- "object-inspect": "^1.9.0",
+ "is-regex": "^1.1.3",
+ "is-string": "^1.0.6",
+ "object-inspect": "^1.10.3",
"object-keys": "^1.1.1",
"object.assign": "^4.1.2",
"string.prototype.trimend": "^1.0.4",
"string.prototype.trimstart": "^1.0.4",
- "unbox-primitive": "^1.0.0"
+ "unbox-primitive": "^1.0.1"
}
},
"es-get-iterator": {
@@ -3267,14 +3238,13 @@
"dev": true
},
"eslint-plugin-import": {
- "version": "2.23.2",
- "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.23.2.tgz",
- "integrity": "sha512-LmNoRptHBxOP+nb0PIKz1y6OSzCJlB+0g0IGS3XV4KaKk2q4szqQ6s6F1utVf5ZRkxk/QOTjdxe7v4VjS99Bsg==",
+ "version": "2.23.4",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz",
+ "integrity": "sha512-6/wP8zZRsnQFiR3iaPFgh5ImVRM1WN5NUWfTIRqwOdeiGJlBcSk82o1FEVq8yXmy4lkIzTo7YhHCIxlU/2HyEQ==",
"dev": true,
"requires": {
"array-includes": "^3.1.3",
"array.prototype.flat": "^1.2.4",
- "contains-path": "^1.0.0",
"debug": "^2.6.9",
"doctrine": "^2.1.0",
"eslint-import-resolver-node": "^0.3.4",
@@ -3340,9 +3310,9 @@
}
},
"eslint-plugin-react": {
- "version": "7.23.2",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.23.2.tgz",
- "integrity": "sha512-AfjgFQB+nYszudkxRkTFu0UR1zEQig0ArVMPloKhxwlwkzaw/fBiH0QWcBBhZONlXqQC51+nfqFrkn4EzHcGBw==",
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.24.0.tgz",
+ "integrity": "sha512-KJJIx2SYx7PBx3ONe/mEeMz4YE0Lcr7feJTCMyyKb/341NcjuAgim3Acgan89GfPv7nxXK2+0slu0CWXYM4x+Q==",
"dev": true,
"requires": {
"array-includes": "^3.1.3",
@@ -3351,12 +3321,12 @@
"has": "^1.0.3",
"jsx-ast-utils": "^2.4.1 || ^3.0.0",
"minimatch": "^3.0.4",
- "object.entries": "^1.1.3",
+ "object.entries": "^1.1.4",
"object.fromentries": "^2.0.4",
- "object.values": "^1.1.3",
+ "object.values": "^1.1.4",
"prop-types": "^15.7.2",
"resolve": "^2.0.0-next.3",
- "string.prototype.matchall": "^4.0.4"
+ "string.prototype.matchall": "^4.0.5"
},
"dependencies": {
"doctrine": {
@@ -3869,9 +3839,9 @@
"dev": true
},
"fast-safe-stringify": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz",
- "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==",
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.8.tgz",
+ "integrity": "sha512-lXatBjf3WPjmWD6DpIZxkeSsCOwqI0maYMpgDlx8g4U2qi4lbjA9oH/HD2a87G+KfsUmo5WbJFmqBZlPxtptag==",
"dev": true
},
"fd-slicer": {
@@ -3907,13 +3877,6 @@
"flat-cache": "^2.0.1"
}
},
- "file-uri-to-path": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
- "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
- "dev": true,
- "optional": true
- },
"filename-regex": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
@@ -4180,6 +4143,15 @@
"optional": true,
"requires": {
"nan": "~0.8.0"
+ },
+ "dependencies": {
+ "nan": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-0.8.0.tgz",
+ "integrity": "sha1-AiqPpen+hCCWSsH7PclOF/RJ9f0=",
+ "dev": true,
+ "optional": true
+ }
}
},
"fstream": {
@@ -4903,9 +4875,9 @@
"dev": true
},
"uglify-js": {
- "version": "3.13.6",
- "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.6.tgz",
- "integrity": "sha512-rRprLwl8RVaS+Qvx3Wh5hPfPBn9++G6xkGlUupya0s5aDmNjI7z3lnRLB3u7sN4OmbB0pWgzhM9BEJyiWAwtAA==",
+ "version": "3.13.10",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.10.tgz",
+ "integrity": "sha512-57H3ACYFXeo1IaZ1w02sfA71wI60MGco/IQFjOqK+WtKoprh7Go2/yvd2HPtoJILO2Or84ncLccI4xoHMTSbGg==",
"dev": true,
"optional": true
},
@@ -5467,9 +5439,9 @@
"dev": true
},
"is-core-module": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz",
- "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==",
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.5.0.tgz",
+ "integrity": "sha512-TXCMSDsEHMEEZ6eCA8rwRDbLu55MRGmrctljsBX/2v1d9/GzqHOxW5c5oPSgrUt2vBFXebu9rGqckXGPWOlYpg==",
"dev": true,
"requires": {
"has": "^1.0.3"
@@ -5917,12 +5889,12 @@
"dev": true
},
"json5": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
- "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
+ "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
"dev": true,
"requires": {
- "minimist": "^1.2.0"
+ "minimist": "^1.2.5"
}
},
"jsonfile": {
@@ -6094,11 +6066,7 @@
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
"dev": true,
- "optional": true,
- "requires": {
- "bindings": "^1.5.0",
- "nan": "^2.12.1"
- }
+ "optional": true
},
"http-proxy": {
"version": "1.18.1",
@@ -6144,13 +6112,6 @@
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"dev": true
},
- "nan": {
- "version": "2.14.2",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
- "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
- "dev": true,
- "optional": true
- },
"object-assign": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz",
@@ -7002,18 +6963,18 @@
"dev": true
},
"mime-db": {
- "version": "1.47.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz",
- "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==",
+ "version": "1.48.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz",
+ "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==",
"dev": true
},
"mime-types": {
- "version": "2.1.30",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz",
- "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==",
+ "version": "2.1.31",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz",
+ "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==",
"dev": true,
"requires": {
- "mime-db": "1.47.0"
+ "mime-db": "1.48.0"
}
},
"mimic-fn": {
@@ -7143,11 +7104,10 @@
"dev": true
},
"nan": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/nan/-/nan-0.8.0.tgz",
- "integrity": "sha1-AiqPpen+hCCWSsH7PclOF/RJ9f0=",
- "dev": true,
- "optional": true
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-1.0.0.tgz",
+ "integrity": "sha1-riT4hQgY1mL8q1rPfzuVv6oszzg=",
+ "dev": true
},
"nanomatch": {
"version": "1.2.13",
@@ -7367,9 +7327,9 @@
}
},
"object-inspect": {
- "version": "1.10.3",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz",
- "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==",
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz",
+ "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==",
"dev": true
},
"object-is": {
@@ -7422,15 +7382,14 @@
}
},
"object.entries": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.3.tgz",
- "integrity": "sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.4.tgz",
+ "integrity": "sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA==",
"dev": true,
"requires": {
- "call-bind": "^1.0.0",
+ "call-bind": "^1.0.2",
"define-properties": "^1.1.3",
- "es-abstract": "^1.18.0-next.1",
- "has": "^1.0.3"
+ "es-abstract": "^1.18.2"
}
},
"object.fromentries": {
@@ -7486,15 +7445,14 @@
}
},
"object.values": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.3.tgz",
- "integrity": "sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz",
+ "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==",
"dev": true,
"requires": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.3",
- "es-abstract": "^1.18.0-next.2",
- "has": "^1.0.3"
+ "es-abstract": "^1.18.2"
}
},
"on-finished": {
@@ -7809,9 +7767,9 @@
"dev": true
},
"path-parse": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
- "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
"path-root": {
@@ -7829,15 +7787,6 @@
"integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=",
"dev": true
},
- "path-starts-with": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/path-starts-with/-/path-starts-with-1.0.0.tgz",
- "integrity": "sha1-soJDAV6LE43lcmgqxS2kLmRq2E4=",
- "dev": true,
- "requires": {
- "normalize-path": "^2.1.1"
- }
- },
"path-to-regexp": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
@@ -8844,14 +8793,6 @@
"array-map": "~0.0.0",
"array-reduce": "~0.0.0",
"jsonify": "~0.0.0"
- },
- "dependencies": {
- "array-filter": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz",
- "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=",
- "dev": true
- }
}
},
"side-channel": {
@@ -9205,9 +9146,9 @@
}
},
"spdx-license-ids": {
- "version": "3.0.8",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.8.tgz",
- "integrity": "sha512-NDgA96EnaLSvtbM7trJj+t1LUR3pirkDCcz9nOUlPb5DMBGsH7oES6C3hs3j7R9oHEa1EMvReS/BUAIT5Tcr0g==",
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz",
+ "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==",
"dev": true
},
"split": {
@@ -9388,15 +9329,16 @@
}
},
"string.prototype.matchall": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.4.tgz",
- "integrity": "sha512-pknFIWVachNcyqRfaQSeu/FUfpvJTe4uskUSZ9Wc1RijsPuzbZ8TyYT8WCNnntCjUEqQ3vUHMAfVj2+wLAisPQ==",
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz",
+ "integrity": "sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q==",
"dev": true,
"requires": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.3",
- "es-abstract": "^1.18.0-next.2",
- "has-symbols": "^1.0.1",
+ "es-abstract": "^1.18.2",
+ "get-intrinsic": "^1.1.1",
+ "has-symbols": "^1.0.2",
"internal-slot": "^1.0.3",
"regexp.prototype.flags": "^1.3.1",
"side-channel": "^1.0.4"
@@ -9776,13 +9718,12 @@
"dev": true
},
"tsconfig-paths": {
- "version": "3.9.0",
- "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz",
- "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==",
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz",
+ "integrity": "sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q==",
"dev": true,
"requires": {
- "@types/json5": "^0.0.29",
- "json5": "^1.0.1",
+ "json5": "^2.2.0",
"minimist": "^1.2.0",
"strip-bom": "^3.0.0"
}
@@ -10396,12 +10337,6 @@
"resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz",
"integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E=",
"dev": true
- },
- "nan": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/nan/-/nan-1.0.0.tgz",
- "integrity": "sha1-riT4hQgY1mL8q1rPfzuVv6oszzg=",
- "dev": true
}
}
},
@@ -10427,9 +10362,9 @@
"dev": true
},
"xmlhttprequest-ssl": {
- "version": "1.5.3",
- "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz",
- "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=",
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz",
+ "integrity": "sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q==",
"dev": true
},
"xtend": {
diff --git a/package.json b/package.json
index aa8380efaa2..13a43e08aa8 100644
--- a/package.json
+++ b/package.json
@@ -1,8 +1,7 @@
{
"name": "@edx/edx-proctoring",
- "//": "Be sure to update the version number in edx_proctoring/__init__.py",
"//": "Note that the version format is slightly different than that of the Python version when using prereleases.",
- "version": "3.18.0",
+ "version": "3.19.0",
"main": "edx_proctoring/static/index.js",
"scripts": {
"test": "gulp test"