Files
edx-platform/lms/static/js/spec/views/fields_helpers.js
Andy Armstrong b2a0b2f728 Improve response handling in AjaxHelpers
I've changed the logic so that AjaxHelpers keeps
track of which requests have not yet had mock
responses sent. This ensures that every response
is handled before moving on to the next one,
rather than always handling the last request.
My intention is that this won't allow bugs to creep
in where a request isn't fired and instead the test
responds to an old request. It also should ensure
that extra events aren't accidentally fired.
2015-09-23 20:23:09 -04:00

268 lines
11 KiB
JavaScript

define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers', 'common/js/spec_helpers/template_helpers',
'js/views/fields',
'string_utils'],
function (Backbone, $, _, AjaxHelpers, TemplateHelpers, FieldViews) {
'use strict';
var API_URL = '/api/end_point/v1';
var USERNAME = 'Legolas',
FULLNAME = 'Legolas Thranduil',
EMAIL = 'legolas@woodland.middlearth',
SELECT_OPTIONS = [['si', 'sindarin'], ['el', 'elvish'], ['na', 'nandor']];
var UserAccountModel = Backbone.Model.extend({
idAttribute: 'username',
defaults: {
username: USERNAME,
name: FULLNAME,
email: EMAIL,
language: SELECT_OPTIONS[0][0]
},
url: API_URL
});
var createFieldData = function (fieldType, fieldData) {
var data = {
model: fieldData.model || new UserAccountModel({}),
title: fieldData.title || 'Field Title',
valueAttribute: fieldData.valueAttribute,
helpMessage: fieldData.helpMessage || 'I am a field message',
placeholderValue: fieldData.placeholderValue || 'I am a placeholder message'
};
switch (fieldType) {
case FieldViews.DropdownFieldView:
data['required'] = fieldData.required || false;
data['options'] = fieldData.options || SELECT_OPTIONS;
break;
case FieldViews.LinkFieldView:
case FieldViews.PasswordFieldView:
data['linkTitle'] = fieldData.linkTitle || "Link Title";
data['linkHref'] = fieldData.linkHref || "/path/to/resource";
data['emailAttribute'] = 'email';
break;
}
_.extend(data, fieldData);
return data;
};
var createErrorMessage = function(attribute, user_message) {
var field_errors = {};
field_errors[attribute] = {
"user_message": user_message
};
return {
"field_errors": field_errors
};
};
var expectTitleToContain = function(view, expectedTitle) {
expect(view.$('.u-field-title').text().trim()).toContain(expectedTitle);
};
var expectMessageContains = function(view, expectedText) {
expect(view.$('.u-field-message').html()).toContain(expectedText);
};
var expectTitleAndMessageToContain = function(view, expectedTitle, expectedMessage) {
expectTitleToContain(view, expectedTitle);
expectMessageContains(view, expectedMessage);
};
var expectAjaxRequestWithData = function(requests, data) {
AjaxHelpers.expectJsonRequest(
requests, 'PATCH', API_URL, data
);
};
var verifyMessageUpdates = function (view, data, timerCallback) {
var message = 'Here to help!';
view.showHelpMessage(message);
expectMessageContains(view, message);
view.showHelpMessage();
expectMessageContains(view, view.helpMessage);
view.showInProgressMessage();
expectMessageContains(view, view.indicators.inProgress);
expectMessageContains(view, view.messages.inProgress);
view.showSuccessMessage();
expectMessageContains(view, view.indicators.success);
expectMessageContains(view, view.getMessage('success'));
expect(timerCallback).not.toHaveBeenCalled();
view.showErrorMessage({
responseText: JSON.stringify(createErrorMessage(data.valueAttribute, 'Ops, try again!.')),
status: 400
});
expectMessageContains(view, view.indicators.validationError);
view.showErrorMessage({status: 500});
expectMessageContains(view, view.indicators.error);
expectMessageContains(view, view.indicators.error);
};
var verifySuccessMessageReset = function (view) {
view.showHelpMessage();
expectMessageContains(view, view.helpMessage);
view.showSuccessMessage();
expectMessageContains(view, view.indicators.success);
jasmine.Clock.tick(7000);
// Message gets reset
expectMessageContains(view, view.helpMessage);
view.showSuccessMessage();
expectMessageContains(view, view.indicators.success);
// But if we change the message, it should not get reset.
view.showHelpMessage("Do not reset this!");
jasmine.Clock.tick(7000);
expectMessageContains(view, "Do not reset this!");
};
var verifyPersistence = function (fieldClass, requests) {
var fieldData = createFieldData(fieldClass, {
title: 'Username',
valueAttribute: 'username',
helpMessage: 'The username that you use to sign in to edX.',
validValue: 'My Name',
persistChanges: false,
messagePosition: 'header'
});
var view = new fieldClass(fieldData).render();
var valueInputSelector;
switch (fieldClass) {
case FieldViews.TextFieldView:
valueInputSelector = '.u-field-value > input';
break;
case FieldViews.DropdownFieldView:
valueInputSelector = '.u-field-value > select';
_.extend(fieldData, {validValue: SELECT_OPTIONS[0][0]});
break;
case FieldViews.TextareaFieldView:
valueInputSelector = '.u-field-value > textarea';
break;
}
view.$(valueInputSelector).val(fieldData.validValue).change();
expect(view.fieldValue()).toBe(fieldData.validValue);
expectMessageContains(view, view.helpMessage);
AjaxHelpers.expectNoRequests(requests);
};
var verifyEditableField = function (view, data, requests) {
var request_data = {};
var url = view.model.url;
if (data.editable === 'toggle') {
expect(view.el).toHaveClass('mode-placeholder');
expectTitleToContain(view, data.title);
expectMessageContains(view, view.indicators.canEdit);
view.$el.click();
} else {
expectTitleAndMessageToContain(view, data.title, data.helpMessage, false);
}
expect(view.el).toHaveClass('mode-edit');
if (view.fieldValue() !== null) {
expect(view.fieldValue()).not.toContain(data.validValue);
}
view.$(data.valueInputSelector).val(data.validValue).change();
// When the value in the field is changed
expect(view.fieldValue()).toBe(data.validValue);
expectMessageContains(view, view.indicators.inProgress);
expectMessageContains(view, view.messages.inProgress);
request_data[data.valueAttribute] = data.validValue;
AjaxHelpers.expectJsonRequest(
requests, 'PATCH', url, request_data
);
AjaxHelpers.respondWithNoContent(requests);
// When server returns success.
if (data.editable === 'toggle') {
expect(view.el).toHaveClass('mode-display');
view.$el.click();
} else {
expectMessageContains(view, view.indicators.success);
}
view.$(data.valueInputSelector).val(data.invalidValue1).change();
request_data[data.valueAttribute] = data.invalidValue1;
AjaxHelpers.expectJsonRequest(
requests, 'PATCH', url, request_data
);
AjaxHelpers.respondWithError(requests, 500);
// When server returns a 500 error
expectMessageContains(view, view.indicators.error);
expectMessageContains(view, view.messages.error);
expect(view.el).toHaveClass('mode-edit');
view.$(data.valueInputSelector).val(data.invalidValue2).change();
request_data[data.valueAttribute] = data.invalidValue2;
AjaxHelpers.expectJsonRequest(
requests, 'PATCH', url, request_data
);
AjaxHelpers.respondWithError(requests, 400, createErrorMessage(data.valueAttribute, data.validationError));
// When server returns a validation error
expectMessageContains(view, view.indicators.validationError);
expectMessageContains(view, data.validationError);
expect(view.el).toHaveClass('mode-edit');
view.$(data.valueInputSelector).val('').change();
// When the value in the field is changed
expect(view.fieldValue()).toBe(data.defaultValue);
request_data[data.valueAttribute] = data.defaultValue;
AjaxHelpers.expectJsonRequest(
requests, 'PATCH', url, request_data
);
AjaxHelpers.respondWithNoContent(requests);
// When server returns success.
if (data.editable === 'toggle') {
expect(view.el).toHaveClass('mode-placeholder');
} else {
expect(view.el).toHaveClass('mode-edit');
}
};
var verifyTextField = function (view, data, requests) {
verifyEditableField(view, _.extend({
valueSelector: '.u-field-value',
valueInputSelector: '.u-field-value > input'
}, data
), requests);
};
var verifyDropDownField = function (view, data, requests) {
verifyEditableField(view, _.extend({
valueSelector: '.u-field-value',
valueInputSelector: '.u-field-value > select'
}, data
), requests);
};
return {
SELECT_OPTIONS: SELECT_OPTIONS,
UserAccountModel: UserAccountModel,
createFieldData: createFieldData,
createErrorMessage: createErrorMessage,
expectTitleToContain: expectTitleToContain,
expectTitleAndMessageToContain: expectTitleAndMessageToContain,
expectMessageContains: expectMessageContains,
expectAjaxRequestWithData: expectAjaxRequestWithData,
verifyMessageUpdates: verifyMessageUpdates,
verifySuccessMessageReset: verifySuccessMessageReset,
verifyEditableField: verifyEditableField,
verifyTextField: verifyTextField,
verifyDropDownField: verifyDropDownField,
verifyPersistence: verifyPersistence
};
});