fields_spec.js 17.4 KB
Newer Older
1
define(['backbone', 'jquery', 'underscore', 'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers',
2
        'common/js/spec_helpers/template_helpers', 'js/views/fields', 'js/spec/views/fields_helpers',
3
        'string_utils'],
4
    function(Backbone, $, _, AjaxHelpers, TemplateHelpers, FieldViews, FieldViewsSpecHelpers) {
5 6 7
        'use strict';

        var USERNAME = 'Legolas',
muzaffaryousaf committed
8
            BIO = "My Name is Theon Greyjoy. I'm member of House Greyjoy";
9

10
        describe('edx.FieldViews', function() {
11
            var requests,
12 13 14
                timerCallback,
                dropdownSelectClass = '.u-field-value > select',
                dropdownButtonClass = '.u-field-value > button',
15
                textareaLinkClass = '.u-field-value .clickable';
16 17 18 19 20 21

            var fieldViewClasses = [
                FieldViews.ReadonlyFieldView,
                FieldViews.TextFieldView,
                FieldViews.DropdownFieldView,
                FieldViews.LinkFieldView,
muzaffaryousaf committed
22
                FieldViews.TextareaFieldView
23 24
            ];

25
            beforeEach(function() {
26
                timerCallback = jasmine.createSpy('timerCallback');
27 28 29 30 31
                jasmine.clock().install();
            });

            afterEach(function() {
                jasmine.clock().uninstall();
32 33
            });

34
            it('updates messages correctly for all fields', function() {
35 36 37 38 39 40 41 42 43 44 45 46 47
                for (var i = 0; i < fieldViewClasses.length; i++) {
                    var fieldViewClass = fieldViewClasses[i];
                    var fieldData = FieldViewsSpecHelpers.createFieldData(fieldViewClass, {
                        title: 'Username',
                        valueAttribute: 'username',
                        helpMessage: 'The username that you use to sign in to edX.'
                    });

                    var view = new fieldViewClass(fieldData).render();
                    FieldViewsSpecHelpers.verifyMessageUpdates(view, fieldData, timerCallback);
                }
            });

48
            it('resets to help message some time after success message is set', function() {
49 50 51 52 53 54
                for (var i = 0; i < fieldViewClasses.length; i++) {
                    var fieldViewClass = fieldViewClasses[i];
                    var fieldData = FieldViewsSpecHelpers.createFieldData(fieldViewClass, {
                        title: 'Username',
                        valueAttribute: 'username',
                        helpMessage: 'The username that you use to sign in to edX.'
muzaffaryousaf committed
55
                    });
56 57 58 59 60 61

                    var view = new fieldViewClass(fieldData).render();
                    FieldViewsSpecHelpers.verifySuccessMessageReset(view, fieldData, timerCallback);
                }
            });

62
            it('sends a PATCH request when saveAttributes is called', function() {
63 64
                requests = AjaxHelpers.requests(this);

muzaffaryousaf committed
65
                var fieldViewClass = FieldViews.EditableFieldView;
66 67 68
                var fieldData = FieldViewsSpecHelpers.createFieldData(fieldViewClass, {
                    title: 'Preferred Language',
                    valueAttribute: 'language',
muhammad-ammar committed
69 70
                    helpMessage: 'Your preferred language.',
                    persistChanges: true
71
                });
72 73 74 75 76 77 78 79 80 81

                var view = new fieldViewClass(fieldData);
                view.saveAttributes(
                    {'language': 'ur'},
                    {'headers': {'Priority': 'Urgent'}}
                );

                var request = requests[0];
                expect(request.method).toBe('PATCH');
                expect(request.requestHeaders['Content-Type']).toBe('application/merge-patch+json;charset=utf-8');
82
                expect(request.requestHeaders.Priority).toBe('Urgent');
83 84 85
                expect(request.requestBody).toBe('{"language":"ur"}');
            });

86
            it('correctly renders and updates ReadonlyFieldView', function() {
87 88 89 90 91 92 93
                var fieldData = FieldViewsSpecHelpers.createFieldData(FieldViews.ReadonlyFieldView, {
                    title: 'Username',
                    valueAttribute: 'username',
                    helpMessage: 'The username that you use to sign in to edX.'
                });
                var view = new FieldViews.ReadonlyFieldView(fieldData).render();

94 95
                FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage);
                expect(view.fieldValue()).toBe(USERNAME);
96 97

                view.model.set({'username': 'bookworm'});
98
                expect(view.fieldValue()).toBe('bookworm');
99 100
            });

101
            it('correctly renders, updates and persists changes to TextFieldView when editable == always', function() {
102 103 104 105 106
                requests = AjaxHelpers.requests(this);

                var fieldData = FieldViewsSpecHelpers.createFieldData(FieldViews.TextFieldView, {
                    title: 'Full Name',
                    valueAttribute: 'name',
muhammad-ammar committed
107 108
                    helpMessage: 'How are you?',
                    persistChanges: true
109 110 111 112 113 114 115 116 117 118
                });
                var view = new FieldViews.TextFieldView(fieldData).render();

                FieldViewsSpecHelpers.verifyTextField(view, {
                    title: fieldData.title,
                    valueAttribute: fieldData.valueAttribute,
                    helpMessage: fieldData.helpMessage,
                    validValue: 'My Name',
                    invalidValue1: 'Your Name',
                    invalidValue2: 'Her Name',
119
                    validationError: 'Think again!',
120
                    defaultValue: ''
121 122 123
                }, requests);
            });

124
            it('correctly renders and updates DropdownFieldView when editable == never', function() {
muzaffaryousaf committed
125 126 127 128 129 130
                requests = AjaxHelpers.requests(this);

                var fieldData = FieldViewsSpecHelpers.createFieldData(FieldViews.DropdownFieldView, {
                    title: 'Full Name',
                    valueAttribute: 'name',
                    helpMessage: 'edX full name',
muhammad-ammar committed
131 132
                    editable: 'never',
                    persistChanges: true
muzaffaryousaf committed
133 134 135

                });
                var view = new FieldViews.DropdownFieldView(fieldData).render();
136 137 138 139
                var readOnlyDisplayClass = '.u-field-value-readonly';

                FieldViewsSpecHelpers.expectDropdownSrTitleToContain(view, fieldData.title);
                FieldViewsSpecHelpers.expectMessageContains(view, fieldData.helpMessage);
muzaffaryousaf committed
140
                expect(view.el).toHaveClass('mode-hidden');
141 142 143 144 145 146 147 148
                // Note that "name" will be retrieved from the model, but the options specified are
                // the languages options. Therefore initially the placeholder message will be shown because
                // the model value does not match any of the possible options.
                expect(view.fieldValue()).toBeNull();
                expect(view.$(readOnlyDisplayClass).text()).toBe(fieldData.placeholderValue);
                // Make sure that the select and the button are not in the HTML.
                expect(view.$(dropdownSelectClass).length).toBe(0);
                expect(view.$(dropdownButtonClass).length).toBe(0);
muzaffaryousaf committed
149 150 151

                view.model.set({'name': fieldData.options[1][0]});
                expect(view.el).toHaveClass('mode-display');
152 153 154
                expect(view.fieldValue()).toBe(fieldData.options[1][0]);
                expect(view.$(readOnlyDisplayClass).text()).toBe(fieldData.options[1][1]);

muzaffaryousaf committed
155 156
                view.$el.click();
                expect(view.el).toHaveClass('mode-display');
157 158 159
                // Make sure that the select and the button still are not in the HTML.
                expect(view.$(dropdownSelectClass).length).toBe(0);
                expect(view.$(dropdownButtonClass).length).toBe(0);
muzaffaryousaf committed
160 161
            });

162
            it('correctly renders, updates and persists changes to DropdownFieldView when editable == always', function() {
163 164 165 166 167
                requests = AjaxHelpers.requests(this);

                var fieldData = FieldViewsSpecHelpers.createFieldData(FieldViews.DropdownFieldView, {
                    title: 'Full Name',
                    valueAttribute: 'name',
muhammad-ammar committed
168 169
                    helpMessage: 'edX full name',
                    persistChanges: true
170 171 172 173 174 175 176 177 178 179
                });
                var view = new FieldViews.DropdownFieldView(fieldData).render();

                FieldViewsSpecHelpers.verifyDropDownField(view, {
                    title: fieldData.title,
                    valueAttribute: fieldData.valueAttribute,
                    helpMessage: fieldData.helpMessage,
                    validValue: FieldViewsSpecHelpers.SELECT_OPTIONS[0][0],
                    invalidValue1: FieldViewsSpecHelpers.SELECT_OPTIONS[1][0],
                    invalidValue2: FieldViewsSpecHelpers.SELECT_OPTIONS[2][0],
180
                    validationError: 'Nope, this will not do!',
181
                    defaultValue: null
182 183 184
                }, requests);
            });

185
            it('correctly renders, updates and persists changes to DropdownFieldView when editable == toggle', function() {
muzaffaryousaf committed
186 187 188 189 190 191
                requests = AjaxHelpers.requests(this);

                var fieldData = FieldViewsSpecHelpers.createFieldData(FieldViews.DropdownFieldView, {
                    title: 'Full Name',
                    valueAttribute: 'name',
                    helpMessage: 'edX full name',
muhammad-ammar committed
192 193
                    editable: 'toggle',
                    persistChanges: true
muzaffaryousaf committed
194 195 196 197 198 199 200 201 202 203 204
                });
                var view = new FieldViews.DropdownFieldView(fieldData).render();

                FieldViewsSpecHelpers.verifyDropDownField(view, {
                    title: fieldData.title,
                    valueAttribute: fieldData.valueAttribute,
                    helpMessage: fieldData.helpMessage,
                    editable: 'toggle',
                    validValue: FieldViewsSpecHelpers.SELECT_OPTIONS[0][0],
                    invalidValue1: FieldViewsSpecHelpers.SELECT_OPTIONS[1][0],
                    invalidValue2: FieldViewsSpecHelpers.SELECT_OPTIONS[2][0],
205
                    validationError: 'Nope, this will not do!',
206
                    defaultValue: null
muzaffaryousaf committed
207 208 209
                }, requests);
            });

210
            it('only shows empty option in DropdownFieldView if required is false or model value is not set', function() {
211 212 213 214 215 216 217 218 219
                requests = AjaxHelpers.requests(this);

                var editableOptions = ['toggle', 'always'];
                _.each(editableOptions, function(editable) {
                    var fieldData = FieldViewsSpecHelpers.createFieldData(FieldViews.DropdownFieldView, {
                        title: 'Drop Down Field',
                        valueAttribute: 'drop-down',
                        helpMessage: 'edX drop down',
                        editable: editable,
220
                        required: true,
muhammad-ammar committed
221
                        persistChanges: true
222 223 224 225 226 227
                    });
                    var view = new FieldViews.DropdownFieldView(fieldData).render();

                    expect(view.modelValueIsSet()).toBe(false);
                    expect(view.displayValue()).toBe('');

228 229 230 231 232 233
                    if (editable === 'toggle') {
                        expect(view.$(dropdownButtonClass).length).toBe(1);
                        view.showEditMode(true);
                    }
                    expect(view.$(dropdownSelectClass).length).toBe(1);
                    view.$(dropdownSelectClass).val(FieldViewsSpecHelpers.SELECT_OPTIONS[0]).change();
234 235 236
                    expect(view.fieldValue()).toBe(FieldViewsSpecHelpers.SELECT_OPTIONS[0][0]);

                    AjaxHelpers.respondWithNoContent(requests);
237
                    if (editable === 'toggle') { view.showEditMode(true); }
238 239 240 241 242
                    // When server returns success, there should no longer be an empty option.
                    expect($(view.$('.u-field-value option')[0]).val()).toBe('si');
                });
            });

243
            it('correctly renders and updates TextAreaFieldView when editable == never', function() {
muzaffaryousaf committed
244 245 246 247
                var fieldData = FieldViewsSpecHelpers.createFieldData(FieldViews.TextareaFieldView, {
                    title: 'About me',
                    valueAttribute: 'bio',
                    helpMessage: 'Wicked is good',
248 249
                    placeholderValue: 'Tell other edX learners a little about yourself: where you live, ' +
                        'what your interests are, why you’re taking courses on edX, or what you hope to learn.',
muhammad-ammar committed
250 251 252
                    editable: 'never',
                    persistChanges: true,
                    messagePosition: 'header'
muzaffaryousaf committed
253 254 255 256 257
                });

                // set bio to empty to see the placeholder.
                fieldData.model.set({bio: ''});
                var view = new FieldViews.TextareaFieldView(fieldData).render();
258
                FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage);
muzaffaryousaf committed
259
                expect(view.el).toHaveClass('mode-hidden');
260 261
                expect(view.fieldValue()).toBe(fieldData.placeholderValue);
                expect(view.$(textareaLinkClass).length).toBe(0);
muzaffaryousaf committed
262

263
                var bio = 'Too much to tell!';
muzaffaryousaf committed
264 265
                view.model.set({'bio': bio});
                expect(view.el).toHaveClass('mode-display');
266
                expect(view.fieldValue()).toBe(bio);
muzaffaryousaf committed
267 268
                view.$el.click();
                expect(view.el).toHaveClass('mode-display');
269
                expect(view.$(textareaLinkClass).length).toBe(0);
muzaffaryousaf committed
270 271
            });

272
            it('correctly renders, updates and persists changes to TextAreaFieldView when editable == toggle', function() {
muzaffaryousaf committed
273 274
                requests = AjaxHelpers.requests(this);

275
                var valueInputSelector = '.u-field-value > textarea';
muzaffaryousaf committed
276 277 278 279
                var fieldData = FieldViewsSpecHelpers.createFieldData(FieldViews.TextareaFieldView, {
                    title: 'About me',
                    valueAttribute: 'bio',
                    helpMessage: 'Wicked is good',
280 281
                    placeholderValue: 'Tell other edX learners a little about yourself: where you live, ' +
                        'what your interests are, why you’re taking courses on edX, or what you hope to learn.',
muhammad-ammar committed
282 283 284
                    editable: 'toggle',
                    persistChanges: true,
                    messagePosition: 'header'
muzaffaryousaf committed
285 286 287 288 289
                });
                fieldData.model.set({'bio': ''});

                var view = new FieldViews.TextareaFieldView(fieldData).render();

290
                FieldViewsSpecHelpers.expectTitleToContain(view, fieldData.title);
291
                FieldViewsSpecHelpers.expectMessageContains(view, view.indicators.canEdit);
muzaffaryousaf committed
292
                expect(view.el).toHaveClass('mode-placeholder');
293 294
                expect(view.fieldValue()).toBe(fieldData.placeholderValue);
                expect(view.$(textareaLinkClass).length).toBe(1);
muzaffaryousaf committed
295 296 297 298 299

                view.$('.wrapper-u-field').click();
                expect(view.el).toHaveClass('mode-edit');
                view.$(valueInputSelector).val(BIO).focusout();
                expect(view.fieldValue()).toBe(BIO);
300
                expect(view.$(textareaLinkClass).length).toBe(0);
muzaffaryousaf committed
301 302 303 304 305
                AjaxHelpers.expectJsonRequest(
                    requests, 'PATCH', view.model.url, {'bio': BIO}
                );
                AjaxHelpers.respondWithNoContent(requests);
                expect(view.el).toHaveClass('mode-display');
306
                expect(view.$(textareaLinkClass).length).toBe(1);
muzaffaryousaf committed
307 308 309 310 311

                view.$('.wrapper-u-field').click();
                view.$(valueInputSelector).val('').focusout();
                AjaxHelpers.respondWithNoContent(requests);
                expect(view.el).toHaveClass('mode-placeholder');
312
                expect(view.fieldValue()).toBe(fieldData.placeholderValue);
muzaffaryousaf committed
313 314
            });

315
            it('correctly renders LinkFieldView', function() {
316 317 318
                var fieldData = FieldViewsSpecHelpers.createFieldData(FieldViews.LinkFieldView, {
                    title: 'Title',
                    linkTitle: 'Link title',
319 320
                    helpMessage: 'Click the link.',
                    valueAttribute: 'password-reset'
321 322 323
                });
                var view = new FieldViews.LinkFieldView(fieldData).render();

324
                FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage);
325
                expect(view.$('.u-field-value > a .u-field-link-title-' + view.options.valueAttribute).text().trim()).toBe(fieldData.linkTitle);
326
            });
muhammad-ammar committed
327

328
            it('correctly renders LinkFieldView', function() {
muhammad-ammar committed
329 330 331 332 333 334 335 336
                var fieldData = FieldViewsSpecHelpers.createFieldData(FieldViews.LinkFieldView, {
                    title: 'Title',
                    linkTitle: 'Link title',
                    helpMessage: 'Click the link.',
                    valueAttribute: 'password-reset'
                });
                var view = new FieldViews.LinkFieldView(fieldData).render();

337
                FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage);
muhammad-ammar committed
338 339 340 341 342 343 344 345 346 347 348 349 350 351
                expect(view.$('.u-field-value > a .u-field-link-title-' + view.options.valueAttribute).text().trim()).toBe(fieldData.linkTitle);
            });

            it("can't persist changes if persistChanges is off", function() {
                requests = AjaxHelpers.requests(this);
                var fieldClasses = [
                    FieldViews.TextFieldView,
                    FieldViews.DropdownFieldView,
                    FieldViews.TextareaFieldView
                ];
                for (var i = 0; i < fieldClasses.length; i++) {
                    FieldViewsSpecHelpers.verifyPersistence(fieldClasses[i], requests);
                }
            });
352 353
        });
    });