This basically commits the transpiled CoffeeScript JS (with minor cleanup) and removes coffee build support. A tiny amount of support for xblocks exists, because external users may have xblocks with coffee. But no coffee in our tree anyway.
693 lines
26 KiB
JavaScript
693 lines
26 KiB
JavaScript
/*
|
|
* decaffeinate suggestions:
|
|
* DS207: Consider shorter variations of null checks
|
|
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
*/
|
|
define(["js/models/metadata", "js/collections/metadata", "js/views/metadata", "cms/js/main"],
|
|
function(MetadataModel, MetadataCollection, MetadataView, main) {
|
|
const verifyInputType = function(input, expectedType) {
|
|
// Some browsers (e.g. FireFox) do not support the "number"
|
|
// input type. We can accept a "text" input instead
|
|
// and still get acceptable behavior in the UI.
|
|
if ((expectedType === 'number') && (input.type !== 'number')) {
|
|
expectedType = 'text';
|
|
}
|
|
expect(input.type).toBe(expectedType);
|
|
};
|
|
|
|
describe("Test Metadata Editor", function() {
|
|
const editorTemplate = readFixtures('metadata-editor.underscore');
|
|
const numberEntryTemplate = readFixtures('metadata-number-entry.underscore');
|
|
const stringEntryTemplate = readFixtures('metadata-string-entry.underscore');
|
|
const optionEntryTemplate = readFixtures('metadata-option-entry.underscore');
|
|
const listEntryTemplate = readFixtures('metadata-list-entry.underscore');
|
|
const dictEntryTemplate = readFixtures('metadata-dict-entry.underscore');
|
|
|
|
beforeEach(function() {
|
|
setFixtures($("<script>", {id: "metadata-editor-tpl", type: "text/template"}).text(editorTemplate));
|
|
appendSetFixtures($("<script>", {id: "metadata-number-entry", type: "text/template"}).text(numberEntryTemplate));
|
|
appendSetFixtures($("<script>", {id: "metadata-string-entry", type: "text/template"}).text(stringEntryTemplate));
|
|
appendSetFixtures($("<script>", {id: "metadata-option-entry", type: "text/template"}).text(optionEntryTemplate));
|
|
appendSetFixtures($("<script>", {id: "metadata-list-entry", type: "text/template"}).text(listEntryTemplate));
|
|
appendSetFixtures($("<script>", {id: "metadata-dict-entry", type: "text/template"}).text(dictEntryTemplate));
|
|
});
|
|
|
|
const genericEntry = {
|
|
default_value: 'default value',
|
|
display_name: "Display Name",
|
|
explicitly_set: true,
|
|
field_name: "display_name",
|
|
help: "Specifies the name for this component.",
|
|
options: [],
|
|
type: MetadataModel.GENERIC_TYPE,
|
|
value: "Word cloud"
|
|
};
|
|
|
|
const selectEntry = {
|
|
default_value: "answered",
|
|
display_name: "Show Answer",
|
|
explicitly_set: false,
|
|
field_name: "show_answer",
|
|
help: "When should you show the answer",
|
|
options: [
|
|
{"display_name": "Always", "value": "always"},
|
|
{"display_name": "Answered", "value": "answered"},
|
|
{"display_name": "Never", "value": "never"}
|
|
],
|
|
type: MetadataModel.SELECT_TYPE,
|
|
value: "always"
|
|
};
|
|
|
|
const integerEntry = {
|
|
default_value: 6,
|
|
display_name: "Inputs",
|
|
explicitly_set: false,
|
|
field_name: "num_inputs",
|
|
help: "Number of text boxes for student to input words/sentences.",
|
|
options: {min: 1},
|
|
type: MetadataModel.INTEGER_TYPE,
|
|
value: 5
|
|
};
|
|
|
|
const floatEntry = {
|
|
default_value: 2.7,
|
|
display_name: "Weight",
|
|
explicitly_set: true,
|
|
field_name: "weight",
|
|
help: "Weight for this problem",
|
|
options: {min: 1.3, max:100.2, step:0.1},
|
|
type: MetadataModel.FLOAT_TYPE,
|
|
value: 10.2
|
|
};
|
|
|
|
const listEntry = {
|
|
default_value: ["a thing", "another thing"],
|
|
display_name: "List",
|
|
explicitly_set: false,
|
|
field_name: "list",
|
|
help: "A list of things.",
|
|
options: [],
|
|
type: MetadataModel.LIST_TYPE,
|
|
value: ["the first display value", "the second"]
|
|
};
|
|
|
|
const timeEntry = {
|
|
default_value: "00:00:00",
|
|
display_name: "Time",
|
|
explicitly_set: true,
|
|
field_name: "relative_time",
|
|
help: "Specifies the name for this component.",
|
|
options: [],
|
|
type: MetadataModel.RELATIVE_TIME_TYPE,
|
|
value: "12:12:12"
|
|
};
|
|
|
|
const dictEntry = {
|
|
default_value: {
|
|
'en': 'English',
|
|
'ru': 'Русский'
|
|
},
|
|
display_name: "New Dict",
|
|
explicitly_set: false,
|
|
field_name: "dict",
|
|
help: "Specifies the name for this component.",
|
|
type: MetadataModel.DICT_TYPE,
|
|
value: {
|
|
'en': 'English',
|
|
'ru': 'Русский',
|
|
'ua': 'Українська',
|
|
'fr': 'Français'
|
|
}
|
|
};
|
|
|
|
|
|
// Test for the editor that creates the individual views.
|
|
describe("MetadataView.Editor creates editors for each field", function() {
|
|
beforeEach(function() {
|
|
this.model = new MetadataCollection(
|
|
[
|
|
integerEntry,
|
|
floatEntry,
|
|
selectEntry,
|
|
genericEntry,
|
|
{
|
|
default_value: null,
|
|
display_name: "Unknown",
|
|
explicitly_set: true,
|
|
field_name: "unknown_type",
|
|
help: "Mystery property.",
|
|
options: [
|
|
{"display_name": "Always", "value": "always"},
|
|
{"display_name": "Answered", "value": "answered"},
|
|
{"display_name": "Never", "value": "never"}],
|
|
type: "unknown type",
|
|
value: null
|
|
},
|
|
listEntry,
|
|
timeEntry,
|
|
dictEntry
|
|
]
|
|
);
|
|
});
|
|
|
|
it("creates child views on initialize, and sorts them alphabetically", function() {
|
|
const view = new MetadataView.Editor({collection: this.model});
|
|
const childModels = view.collection.models;
|
|
expect(childModels.length).toBe(8);
|
|
// Be sure to check list view as well as other input types
|
|
const childViews = view.$el.find('.setting-input, .list-settings');
|
|
expect(childViews.length).toBe(8);
|
|
|
|
const verifyEntry = function(index, display_name, type) {
|
|
expect(childModels[index].get('display_name')).toBe(display_name);
|
|
verifyInputType(childViews[index], type);
|
|
};
|
|
|
|
verifyEntry(0, 'Display Name', 'text');
|
|
verifyEntry(1, 'Inputs', 'number');
|
|
verifyEntry(2, 'List', '');
|
|
verifyEntry(3, 'New Dict', '');
|
|
verifyEntry(4, 'Show Answer', 'select-one');
|
|
verifyEntry(5, 'Time', 'text');
|
|
verifyEntry(6, 'Unknown', 'text');
|
|
verifyEntry(7, 'Weight', 'number');
|
|
});
|
|
|
|
it("returns its display name", function() {
|
|
const view = new MetadataView.Editor({collection: this.model});
|
|
expect(view.getDisplayName()).toBe("Word cloud");
|
|
});
|
|
|
|
it("returns an empty string if there is no display name property with a valid value", function() {
|
|
let view = new MetadataView.Editor({collection: new MetadataCollection()});
|
|
expect(view.getDisplayName()).toBe("");
|
|
|
|
view = new MetadataView.Editor({collection: new MetadataCollection([
|
|
{
|
|
default_value: null,
|
|
display_name: "Display Name",
|
|
explicitly_set: false,
|
|
field_name: "display_name",
|
|
help: "",
|
|
options: [],
|
|
type: MetadataModel.GENERIC_TYPE,
|
|
value: null
|
|
|
|
}])
|
|
});
|
|
expect(view.getDisplayName()).toBe("");
|
|
});
|
|
|
|
it("has no modified values by default", function() {
|
|
const view = new MetadataView.Editor({collection: this.model});
|
|
expect(view.getModifiedMetadataValues()).toEqual({});
|
|
});
|
|
|
|
it("returns modified values only", function() {
|
|
const view = new MetadataView.Editor({collection: this.model});
|
|
const childModels = view.collection.models;
|
|
childModels[0].setValue('updated display name');
|
|
childModels[1].setValue(20);
|
|
expect(view.getModifiedMetadataValues()).toEqual({
|
|
display_name : 'updated display name',
|
|
num_inputs: 20
|
|
});
|
|
});
|
|
});
|
|
|
|
// Tests for individual views.
|
|
const assertInputType = function(view, expectedType) {
|
|
const input = view.$el.find('.setting-input');
|
|
expect(input.length).toEqual(1);
|
|
verifyInputType(input[0], expectedType);
|
|
};
|
|
|
|
const assertValueInView = (view, expectedValue) => expect(view.getValueFromEditor()).toEqual(expectedValue);
|
|
|
|
const assertCanUpdateView = function(view, newValue) {
|
|
view.setValueInEditor(newValue);
|
|
expect(view.getValueFromEditor()).toEqual(newValue);
|
|
};
|
|
|
|
const assertClear = function(view, modelValue, editorValue) {
|
|
if (editorValue == null) { editorValue = modelValue; }
|
|
view.clear();
|
|
expect(view.model.getValue()).toBe(null);
|
|
expect(view.model.getDisplayValue()).toEqual(modelValue);
|
|
expect(view.getValueFromEditor()).toEqual(editorValue);
|
|
};
|
|
|
|
const assertUpdateModel = function(view, originalValue, newValue) {
|
|
view.setValueInEditor(newValue);
|
|
expect(view.model.getValue()).toEqual(originalValue);
|
|
view.updateModel();
|
|
expect(view.model.getValue()).toEqual(newValue);
|
|
};
|
|
|
|
describe("MetadataView.String is a basic string input with clear functionality", function() {
|
|
beforeEach(function() {
|
|
const model = new MetadataModel(genericEntry);
|
|
this.view = new MetadataView.String({model});
|
|
});
|
|
|
|
it("uses a text input type", function() {
|
|
assertInputType(this.view, 'text');
|
|
});
|
|
|
|
it("returns the intial value upon initialization", function() {
|
|
assertValueInView(this.view, 'Word cloud');
|
|
});
|
|
|
|
it("can update its value in the view", function() {
|
|
assertCanUpdateView(this.view, "updated ' \" &");
|
|
});
|
|
|
|
it("has a clear method to revert to the model default", function() {
|
|
assertClear(this.view, 'default value');
|
|
});
|
|
|
|
it("has an update model method", function() {
|
|
assertUpdateModel(this.view, 'Word cloud', 'updated');
|
|
});
|
|
});
|
|
|
|
describe("MetadataView.Option is an option input type with clear functionality", function() {
|
|
beforeEach(function() {
|
|
const model = new MetadataModel(selectEntry);
|
|
this.view = new MetadataView.Option({model});
|
|
});
|
|
|
|
it("uses a select input type", function() {
|
|
assertInputType(this.view, 'select-one');
|
|
});
|
|
|
|
it("returns the intial value upon initialization", function() {
|
|
assertValueInView(this.view, 'always');
|
|
});
|
|
|
|
it("can update its value in the view", function() {
|
|
assertCanUpdateView(this.view, "never");
|
|
});
|
|
|
|
it("has a clear method to revert to the model default", function() {
|
|
assertClear(this.view, 'answered');
|
|
});
|
|
|
|
it("has an update model method", function() {
|
|
assertUpdateModel(this.view, null, 'never');
|
|
});
|
|
|
|
it("does not update to a value that is not an option", function() {
|
|
this.view.setValueInEditor("not an option");
|
|
expect(this.view.getValueFromEditor()).toBe('always');
|
|
});
|
|
});
|
|
|
|
describe("MetadataView.Number supports integer or float type and has clear functionality", function() {
|
|
const verifyValueAfterChanged = function(view, value, expectedResult) {
|
|
view.setValueInEditor(value);
|
|
view.changed();
|
|
expect(view.getValueFromEditor()).toBe(expectedResult);
|
|
};
|
|
|
|
beforeEach(function() {
|
|
const integerModel = new MetadataModel(integerEntry);
|
|
this.integerView = new MetadataView.Number({model: integerModel});
|
|
|
|
const floatModel = new MetadataModel(floatEntry);
|
|
this.floatView = new MetadataView.Number({model: floatModel});
|
|
});
|
|
|
|
it("uses a number input type", function() {
|
|
assertInputType(this.integerView, 'number');
|
|
assertInputType(this.floatView, 'number');
|
|
});
|
|
|
|
it("returns the intial value upon initialization", function() {
|
|
assertValueInView(this.integerView, '5');
|
|
assertValueInView(this.floatView, '10.2');
|
|
});
|
|
|
|
it("can update its value in the view", function() {
|
|
assertCanUpdateView(this.integerView, "12");
|
|
assertCanUpdateView(this.floatView, "-2.4");
|
|
});
|
|
|
|
it("has a clear method to revert to the model default", function() {
|
|
assertClear(this.integerView, 6, '6');
|
|
assertClear(this.floatView, 2.7, '2.7');
|
|
});
|
|
|
|
it("has an update model method", function() {
|
|
assertUpdateModel(this.integerView, null, '90');
|
|
assertUpdateModel(this.floatView, 10.2, '-9.5');
|
|
});
|
|
|
|
it("knows the difference between integer and float", function() {
|
|
expect(this.integerView.isIntegerField()).toBeTruthy();
|
|
expect(this.floatView.isIntegerField()).toBeFalsy();
|
|
});
|
|
|
|
it("sets attribtues related to min, max, and step", function() {
|
|
const verifyAttributes = function(view, min, step, max=null) {
|
|
const inputEntry = view.$el.find('input');
|
|
expect(Number(inputEntry.attr('min'))).toEqual(min);
|
|
expect(Number(inputEntry.attr('step'))).toEqual(step);
|
|
if (max === !null) {
|
|
expect(Number(inputEntry.attr('max'))).toEqual(max);
|
|
}
|
|
};
|
|
|
|
verifyAttributes(this.integerView, 1, 1);
|
|
verifyAttributes(this.floatView, 1.3, .1, 100.2);
|
|
});
|
|
|
|
it("corrects values that are out of range", function() {
|
|
verifyValueAfterChanged(this.integerView, '-4', '1');
|
|
verifyValueAfterChanged(this.integerView, '1', '1');
|
|
verifyValueAfterChanged(this.integerView, '0', '1');
|
|
verifyValueAfterChanged(this.integerView, '3001', '3001');
|
|
|
|
verifyValueAfterChanged(this.floatView, '-4', '1.3');
|
|
verifyValueAfterChanged(this.floatView, '1.3', '1.3');
|
|
verifyValueAfterChanged(this.floatView, '1.2', '1.3');
|
|
verifyValueAfterChanged(this.floatView, '100.2', '100.2');
|
|
verifyValueAfterChanged(this.floatView, '100.3', '100.2');
|
|
});
|
|
|
|
it("sets default values for integer and float fields that are empty", function() {
|
|
verifyValueAfterChanged(this.integerView, '', '6');
|
|
verifyValueAfterChanged(this.floatView, '', '2.7');
|
|
});
|
|
|
|
it("disallows invalid characters", function() {
|
|
const verifyValueAfterKeyPressed = function(view, character, reject) {
|
|
const event = {
|
|
type : 'keypress',
|
|
which : character.charCodeAt(0),
|
|
keyCode: character.charCodeAt(0),
|
|
preventDefault() { return 'no op'; }
|
|
};
|
|
spyOn(event, 'preventDefault');
|
|
view.$el.find('input').trigger(event);
|
|
if (reject) {
|
|
expect(event.preventDefault).toHaveBeenCalled();
|
|
} else {
|
|
expect(event.preventDefault).not.toHaveBeenCalled();
|
|
}
|
|
};
|
|
|
|
const verifyDisallowedChars = function(view) {
|
|
verifyValueAfterKeyPressed(view, 'a', true);
|
|
verifyValueAfterKeyPressed(view, '.', view.isIntegerField());
|
|
verifyValueAfterKeyPressed(view, '[', true);
|
|
verifyValueAfterKeyPressed(view, '@', true);
|
|
|
|
[0, 1, 2, 3, 4, 5, 6, 7, 8].map((i) =>
|
|
verifyValueAfterKeyPressed(view, String(i), false));
|
|
};
|
|
|
|
verifyDisallowedChars(this.integerView);
|
|
verifyDisallowedChars(this.floatView);
|
|
});
|
|
});
|
|
|
|
describe("MetadataView.List allows the user to enter an ordered list of strings", function() {
|
|
beforeEach(function() {
|
|
const listModel = new MetadataModel(listEntry);
|
|
this.listView = new MetadataView.List({model: listModel});
|
|
this.el = this.listView.$el;
|
|
main();
|
|
});
|
|
|
|
it("returns the initial value upon initialization", function() {
|
|
assertValueInView(this.listView, ['the first display value', 'the second']);
|
|
});
|
|
|
|
it("updates its value correctly", function() {
|
|
assertCanUpdateView(this.listView, ['a new item', 'another new item', 'a third']);
|
|
});
|
|
|
|
it("has a clear method to revert to the model default", function() {
|
|
this.el.find('.create-setting').click();
|
|
assertClear(this.listView, ['a thing', 'another thing']);
|
|
expect(this.el.find('.create-setting')).not.toHaveClass('is-disabled');
|
|
});
|
|
|
|
it("has an update model method", function() {
|
|
assertUpdateModel(this.listView, null, ['a new value']);
|
|
});
|
|
|
|
it("can add an entry", function() {
|
|
expect(this.listView.model.get('value').length).toEqual(2);
|
|
this.el.find('.create-setting').click();
|
|
expect(this.el.find('input.input').length).toEqual(3);
|
|
});
|
|
|
|
it("can remove an entry", function() {
|
|
expect(this.listView.model.get('value').length).toEqual(2);
|
|
this.el.find('.remove-setting').first().click();
|
|
expect(this.listView.model.get('value').length).toEqual(1);
|
|
});
|
|
|
|
it("only allows one blank entry at a time", function() {
|
|
expect(this.el.find('input').length).toEqual(2);
|
|
this.el.find('.create-setting').click();
|
|
this.el.find('.create-setting').click();
|
|
expect(this.el.find('input').length).toEqual(3);
|
|
});
|
|
|
|
it("re-enables the add setting button after entering a new value", function() {
|
|
expect(this.el.find('input').length).toEqual(2);
|
|
this.el.find('.create-setting').click();
|
|
expect(this.el.find('.create-setting')).toHaveClass('is-disabled');
|
|
this.el.find('input').last().val('third setting');
|
|
this.el.find('input').last().trigger('input');
|
|
expect(this.el.find('.create-setting')).not.toHaveClass('is-disabled');
|
|
});
|
|
});
|
|
|
|
describe("MetadataView.RelativeTime allows the user to enter time string in HH:mm:ss format", function() {
|
|
beforeEach(function() {
|
|
const model = new MetadataModel(timeEntry);
|
|
this.view = new MetadataView.RelativeTime({model});
|
|
});
|
|
|
|
it("uses a text input type", function() {
|
|
assertInputType(this.view, 'text');
|
|
});
|
|
|
|
it("returns the intial value upon initialization", function() {
|
|
assertValueInView(this.view, '12:12:12');
|
|
});
|
|
|
|
it("value is converted correctly", function() {
|
|
const { view } = this;
|
|
|
|
const cases = [
|
|
{
|
|
input: '23:100:0',
|
|
output: '23:59:59'
|
|
},
|
|
{
|
|
input: '100000000000000000',
|
|
output: '23:59:59'
|
|
},
|
|
{
|
|
input: '80000',
|
|
output: '22:13:20'
|
|
},
|
|
{
|
|
input: '-100',
|
|
output: '00:00:00'
|
|
},
|
|
{
|
|
input: '-100:-10',
|
|
output: '00:00:00'
|
|
},
|
|
{
|
|
input: '99:99',
|
|
output: '01:40:39'
|
|
},
|
|
{
|
|
input: '2',
|
|
output: '00:00:02'
|
|
},
|
|
{
|
|
input: '1:2',
|
|
output: '00:01:02'
|
|
},
|
|
{
|
|
input: '1:25',
|
|
output: '00:01:25'
|
|
},
|
|
{
|
|
input: '3:1:25',
|
|
output: '03:01:25'
|
|
},
|
|
{
|
|
input: ' 2 3 : 5 9 : 5 9 ',
|
|
output: '23:59:59'
|
|
},
|
|
{
|
|
input: '9:1:25',
|
|
output: '09:01:25'
|
|
},
|
|
{
|
|
input: '77:72:77',
|
|
output: '23:59:59'
|
|
},
|
|
{
|
|
input: '22:100:100',
|
|
output: '23:41:40'
|
|
},
|
|
// negative value
|
|
{
|
|
input: '-22:22:22',
|
|
output: '00:22:22'
|
|
},
|
|
// simple string
|
|
{
|
|
input: 'simple text',
|
|
output: '00:00:00'
|
|
},
|
|
{
|
|
input: 'a10a:a10a:a10a',
|
|
output: '00:00:00'
|
|
},
|
|
// empty string
|
|
{
|
|
input: '',
|
|
output: '00:00:00'
|
|
}
|
|
];
|
|
|
|
$.each(cases, (index, data) => expect(view.parseRelativeTime(data.input)).toBe(data.output));
|
|
});
|
|
|
|
it("can update its value in the view", function() {
|
|
assertCanUpdateView(this.view, "23:59:59");
|
|
this.view.setValueInEditor("33:59:59");
|
|
this.view.updateModel();
|
|
assertValueInView(this.view, "23:59:59");
|
|
});
|
|
|
|
it("has a clear method to revert to the model default", function() {
|
|
assertClear(this.view, '00:00:00');
|
|
});
|
|
|
|
it("has an update model method", function() {
|
|
assertUpdateModel(this.view, '12:12:12', '23:59:59');
|
|
});
|
|
});
|
|
|
|
describe("MetadataView.Dict allows the user to enter key-value pairs of strings", function() {
|
|
beforeEach(function() {
|
|
const dictModel = new MetadataModel($.extend(true, {}, dictEntry));
|
|
this.dictView = new MetadataView.Dict({model: dictModel});
|
|
this.el = this.dictView.$el;
|
|
main();
|
|
});
|
|
|
|
it("returns the initial value upon initialization", function() {
|
|
assertValueInView(this.dictView, {
|
|
'en': 'English',
|
|
'ru': 'Русский',
|
|
'ua': 'Українська',
|
|
'fr': 'Français'
|
|
});
|
|
});
|
|
|
|
it("updates its value correctly", function() {
|
|
assertCanUpdateView(this.dictView, {
|
|
'ru': 'Русский',
|
|
'ua': 'Українська',
|
|
'fr': 'Français'
|
|
});
|
|
});
|
|
|
|
it("has a clear method to revert to the model default", function() {
|
|
this.el.find('.create-setting').click();
|
|
assertClear(this.dictView, {
|
|
'en': 'English',
|
|
'ru': 'Русский'
|
|
});
|
|
expect(this.el.find('.create-setting')).not.toHaveClass('is-disabled');
|
|
});
|
|
|
|
it("has an update model method", function() {
|
|
assertUpdateModel(this.dictView, null, {'fr': 'Français'});
|
|
});
|
|
|
|
it("can add an entry", function() {
|
|
expect(_.keys(this.dictView.model.get('value')).length).toEqual(4);
|
|
this.el.find('.create-setting').click();
|
|
expect(this.el.find('input.input-key').length).toEqual(5);
|
|
});
|
|
|
|
it("can remove an entry", function() {
|
|
expect(_.keys(this.dictView.model.get('value')).length).toEqual(4);
|
|
this.el.find('.remove-setting').first().click();
|
|
expect(_.keys(this.dictView.model.get('value')).length).toEqual(3);
|
|
});
|
|
|
|
it("only allows one blank entry at a time", function() {
|
|
expect(this.el.find('input.input-key').length).toEqual(4);
|
|
this.el.find('.create-setting').click();
|
|
this.el.find('.create-setting').click();
|
|
expect(this.el.find('input.input-key').length).toEqual(5);
|
|
});
|
|
|
|
it("only allows unique keys", function() {
|
|
const data = [
|
|
{
|
|
expectedValue: {'ru': 'Русский'},
|
|
initialValue: {'ru': 'Русский'},
|
|
testValue: {
|
|
'key': 'ru',
|
|
'value': ''
|
|
}
|
|
},
|
|
{
|
|
expectedValue: {'ru': 'Русский'},
|
|
initialValue: {'ru': 'Some value'},
|
|
testValue: {
|
|
'key': 'ru',
|
|
'value': 'Русский'
|
|
}
|
|
},
|
|
{
|
|
expectedValue: {'ru': 'Русский'},
|
|
initialValue: {'ru': 'Русский'},
|
|
testValue: {
|
|
'key': '',
|
|
'value': ''
|
|
}
|
|
}
|
|
];
|
|
|
|
_.each(data, ((d, index) => {
|
|
this.dictView.setValueInEditor(d.initialValue);
|
|
this.dictView.updateModel();
|
|
this.el.find('.create-setting').click();
|
|
const item = this.el.find('.list-settings-item').last();
|
|
item.find('.input-key').val(d.testValue.key);
|
|
item.find('.input-value').val(d.testValue.value);
|
|
|
|
expect(this.dictView.getValueFromEditor()).toEqual(d.expectedValue);
|
|
})
|
|
);
|
|
});
|
|
|
|
it("re-enables the add setting button after entering a new value", function() {
|
|
expect(this.el.find('input.input-key').length).toEqual(4);
|
|
this.el.find('.create-setting').click();
|
|
expect(this.el.find('.create-setting')).toHaveClass('is-disabled');
|
|
this.el.find('input.input-key').last().val('third setting');
|
|
this.el.find('input.input-key').last().trigger('input');
|
|
expect(this.el.find('.create-setting')).not.toHaveClass('is-disabled');
|
|
});
|
|
});
|
|
});
|
|
});
|