debian-mirror-gitlab/spec/frontend/notes/deprecated_notes_spec.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

989 lines
31 KiB
JavaScript
Raw Normal View History

2019-09-04 21:01:54 +05:30
/* eslint-disable import/no-commonjs, no-new */
2018-03-17 18:26:18 +05:30
import MockAdapter from 'axios-mock-adapter';
2021-03-11 19:13:27 +05:30
import $ from 'jquery';
2018-05-09 12:01:36 +05:30
import '~/behaviors/markdown/render_gfm';
2022-07-16 23:28:13 +05:30
import { loadHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
2019-09-04 21:01:54 +05:30
import { createSpyObj } from 'helpers/jest_helpers';
import { TEST_HOST } from 'helpers/test_constants';
2022-04-04 11:22:00 +05:30
import waitForPromises from 'helpers/wait_for_promises';
2021-03-11 19:13:27 +05:30
import { setTestTimeoutOnce } from 'helpers/timeout';
2020-01-01 13:55:28 +05:30
import axios from '~/lib/utils/axios_utils';
2021-03-11 19:13:27 +05:30
import * as urlUtility from '~/lib/utils/url_utility';
2019-09-04 21:01:54 +05:30
// These must be imported synchronously because they pull dependencies
// from the DOM.
window.jQuery = $;
require('autosize');
require('~/commons');
2021-11-11 11:23:49 +05:30
const Notes = require('~/deprecated_notes').default;
2019-09-04 21:01:54 +05:30
const FLASH_TYPE_ALERT = 'alert';
const NOTES_POST_PATH = /(.*)\/notes\?html=true$/;
const fixture = 'snippets/show.html';
let mockAxios;
window.project_uploads_path = `${TEST_HOST}/uploads`;
window.gon = window.gon || {};
2018-12-13 13:39:08 +05:30
window.gl = window.gl || {};
gl.utils = gl.utils || {};
2019-09-04 21:01:54 +05:30
gl.utils.disableButtonIfEmptyField = () => {};
2018-12-13 13:39:08 +05:30
2021-06-08 01:23:25 +05:30
// the following test is unreliable and failing in main 2-3 times a day
2020-04-08 14:13:33 +05:30
// see https://gitlab.com/gitlab-org/gitlab/issues/206906#note_290602581
// eslint-disable-next-line jest/no-disabled-tests
2021-11-11 11:23:49 +05:30
describe.skip('Old Notes (~/deprecated_notes.js)', () => {
2019-09-04 21:01:54 +05:30
beforeEach(() => {
2022-07-16 23:28:13 +05:30
loadHTMLFixture(fixture);
2019-09-04 21:01:54 +05:30
// Re-declare this here so that test_setup.js#beforeEach() doesn't
// overwrite it.
mockAxios = new MockAdapter(axios);
2016-09-29 09:46:39 +05:30
2019-09-04 21:01:54 +05:30
$.ajax = () => {
throw new Error('$.ajax should not be called through!');
};
2018-03-17 18:26:18 +05:30
2019-09-04 21:01:54 +05:30
// These jQuery+DOM tests are super flaky so increase the timeout to avoid
// random failures.
// It seems that running tests in parallel increases failure rate.
jest.setTimeout(4000);
setTestTimeoutOnce(4000);
});
2017-08-17 22:00:37 +05:30
2022-07-16 23:28:13 +05:30
afterEach(async () => {
2019-09-04 21:01:54 +05:30
// The Notes component sets a polling interval. Clear it after every run.
// Make sure to use jest.runOnlyPendingTimers() instead of runAllTimers().
jest.clearAllTimers();
2022-07-16 23:28:13 +05:30
await axios.waitForAll().finally(() => mockAxios.restore());
resetHTMLFixture();
2018-12-13 13:39:08 +05:30
});
2018-05-09 12:01:36 +05:30
2019-09-04 21:01:54 +05:30
it('loads the Notes class into the DOM', () => {
expect(Notes).toBeDefined();
expect(Notes.name).toBe('Notes');
2018-12-13 13:39:08 +05:30
});
2018-05-09 12:01:36 +05:30
2018-12-13 13:39:08 +05:30
describe('addBinding', () => {
it('calls postComment when comment button is clicked', () => {
2019-09-04 21:01:54 +05:30
jest.spyOn(Notes.prototype, 'postComment');
2018-12-13 13:39:08 +05:30
2021-11-11 11:23:49 +05:30
new Notes('', []);
2018-12-13 13:39:08 +05:30
$('.js-comment-button').click();
expect(Notes.prototype.postComment).toHaveBeenCalled();
2018-05-09 12:01:36 +05:30
});
2018-12-13 13:39:08 +05:30
});
2018-05-09 12:01:36 +05:30
2019-09-04 21:01:54 +05:30
describe('task lists', () => {
beforeEach(() => {
mockAxios.onAny().reply(200, {});
new Notes('', []);
2018-12-13 13:39:08 +05:30
});
2018-03-17 18:26:18 +05:30
2019-09-04 21:01:54 +05:30
it('modifies the Markdown field', () => {
2018-12-13 13:39:08 +05:30
const changeEvent = document.createEvent('HTMLEvents');
changeEvent.initEvent('change', true, true);
2021-03-08 18:12:59 +05:30
$('input[type=checkbox]').attr('checked', true)[0].dispatchEvent(changeEvent);
2018-03-17 18:26:18 +05:30
2018-12-13 13:39:08 +05:30
expect($('.js-task-list-field.original-task-list').val()).toBe('- [x] Task List Item');
});
2016-09-29 09:46:39 +05:30
2019-09-04 21:01:54 +05:30
it('submits an ajax request on tasklist:changed', () => {
jest.spyOn(axios, 'patch');
2019-03-02 22:35:43 +05:30
const lineNumber = 8;
const lineSource = '- [ ] item 8';
const index = 3;
const checked = true;
$('.js-task-list-container').trigger({
type: 'tasklist:changed',
detail: { lineNumber, lineSource, index, checked },
});
2018-03-17 18:26:18 +05:30
2019-09-04 21:01:54 +05:30
expect(axios.patch).toHaveBeenCalledWith(undefined, {
note: {
note: '',
lock_version: undefined,
update_task: { index, checked, line_number: lineNumber, line_source: lineSource },
},
2016-09-29 09:46:39 +05:30
});
});
2018-12-13 13:39:08 +05:30
});
2016-09-29 09:46:39 +05:30
2019-09-04 21:01:54 +05:30
describe('comments', () => {
let notes;
let autosizeSpy;
let textarea;
2016-09-29 09:46:39 +05:30
2019-09-04 21:01:54 +05:30
beforeEach(() => {
notes = new Notes('', []);
2016-09-29 09:46:39 +05:30
2019-09-04 21:01:54 +05:30
textarea = $('.js-note-text');
textarea.data('autosave', {
reset: () => {},
2018-12-13 13:39:08 +05:30
});
2019-09-04 21:01:54 +05:30
autosizeSpy = jest.fn();
$(textarea).on('autosize:update', autosizeSpy);
jest.spyOn(notes, 'renderNote');
2016-09-29 09:46:39 +05:30
2021-03-08 18:12:59 +05:30
$('.js-comment-button').on('click', (e) => {
2018-12-13 13:39:08 +05:30
const $form = $(this);
e.preventDefault();
2019-09-04 21:01:54 +05:30
notes.addNote($form, {});
notes.reenableTargetFormSubmitButton(e);
notes.resetMainTargetForm(e);
2016-09-13 17:45:13 +05:30
});
2018-12-13 13:39:08 +05:30
});
2016-09-29 09:46:39 +05:30
2019-09-04 21:01:54 +05:30
it('autosizes after comment submission', () => {
textarea.text('This is an example comment note');
expect(autosizeSpy).not.toHaveBeenCalled();
2018-12-13 13:39:08 +05:30
$('.js-comment-button').click();
2019-09-04 21:01:54 +05:30
expect(autosizeSpy).toHaveBeenCalled();
2016-09-13 17:45:13 +05:30
});
2019-09-04 21:01:54 +05:30
it('should not place escaped text in the comment box in case of error', () => {
2018-12-13 13:39:08 +05:30
const deferred = $.Deferred();
2019-09-04 21:01:54 +05:30
jest.spyOn($, 'ajax').mockReturnValueOnce(deferred);
2018-12-13 13:39:08 +05:30
$(textarea).text('A comment with `markup`.');
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
deferred.reject();
$('.js-comment-button').click();
2018-03-17 18:26:18 +05:30
2019-09-04 21:01:54 +05:30
expect($(textarea).val()).toBe('A comment with `markup`.');
$.ajax.mockRestore();
expect($.ajax.mock).toBeUndefined();
2018-12-13 13:39:08 +05:30
});
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
describe('updateNote', () => {
2019-09-04 21:01:54 +05:30
let notes;
2018-12-13 13:39:08 +05:30
let noteEntity;
let $notesContainer;
beforeEach(() => {
2019-09-04 21:01:54 +05:30
notes = new Notes('', []);
2018-12-13 13:39:08 +05:30
window.gon.current_username = 'root';
window.gon.current_user_fullname = 'Administrator';
2019-09-04 21:01:54 +05:30
const sampleComment = 'foo';
2018-12-13 13:39:08 +05:30
noteEntity = {
id: 1234,
html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
<div class="note-text">${sampleComment}</div>
</li>`,
note: sampleComment,
valid: true,
};
2019-09-04 21:01:54 +05:30
2018-12-13 13:39:08 +05:30
$notesContainer = $('ul.main-notes-list');
2019-09-04 21:01:54 +05:30
const $form = $('form.js-main-target-form');
2018-12-13 13:39:08 +05:30
$form.find('textarea.js-note-text').val(sampleComment);
2019-09-04 21:01:54 +05:30
mockAxios.onPost(NOTES_POST_PATH).reply(200, noteEntity);
2018-12-13 13:39:08 +05:30
});
2017-08-17 22:00:37 +05:30
2019-09-04 21:01:54 +05:30
it('updates note and resets edit form', () => {
jest.spyOn(notes, 'revertNoteEditForm');
jest.spyOn(notes, 'setupNewNote');
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
$('.js-comment-button').click();
2018-03-17 18:26:18 +05:30
2019-09-04 21:01:54 +05:30
const $targetNote = $notesContainer.find(`#note_${noteEntity.id}`);
2020-05-24 23:13:21 +05:30
const updatedNote = { ...noteEntity };
2019-09-04 21:01:54 +05:30
updatedNote.note = 'bar';
notes.updateNote(updatedNote, $targetNote);
2018-12-13 13:39:08 +05:30
2019-09-04 21:01:54 +05:30
expect(notes.revertNoteEditForm).toHaveBeenCalledWith($targetNote);
expect(notes.setupNewNote).toHaveBeenCalled();
2017-09-10 17:25:29 +05:30
});
2018-12-13 13:39:08 +05:30
});
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
describe('updateNoteTargetSelector', () => {
const hash = 'note_foo';
let $note;
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
beforeEach(() => {
$note = $(`<div id="${hash}"></div>`);
2019-09-04 21:01:54 +05:30
jest.spyOn($note, 'filter');
jest.spyOn($note, 'toggleClass');
});
// urlUtility is a dependency of the notes module. Its getLocatinHash() method should be called internally.
2018-12-13 13:39:08 +05:30
it('sets target when hash matches', () => {
2019-09-04 21:01:54 +05:30
jest.spyOn(urlUtility, 'getLocationHash').mockReturnValueOnce(hash);
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
Notes.updateNoteTargetSelector($note);
2017-09-10 17:25:29 +05:30
2019-09-04 21:01:54 +05:30
expect(urlUtility.getLocationHash).toHaveBeenCalled();
2018-12-13 13:39:08 +05:30
expect($note.filter).toHaveBeenCalledWith(`#${hash}`);
expect($note.toggleClass).toHaveBeenCalledWith('target', true);
});
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
it('unsets target when hash does not match', () => {
2019-09-04 21:01:54 +05:30
jest.spyOn(urlUtility, 'getLocationHash').mockReturnValueOnce('note_doesnotexist');
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
Notes.updateNoteTargetSelector($note);
2017-09-10 17:25:29 +05:30
2019-09-04 21:01:54 +05:30
expect(urlUtility.getLocationHash).toHaveBeenCalled();
2018-12-13 13:39:08 +05:30
expect($note.toggleClass).toHaveBeenCalledWith('target', false);
});
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
it('unsets target when there is not a hash fragment anymore', () => {
2019-09-04 21:01:54 +05:30
jest.spyOn(urlUtility, 'getLocationHash').mockReturnValueOnce(null);
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
Notes.updateNoteTargetSelector($note);
2017-09-10 17:25:29 +05:30
2019-09-04 21:01:54 +05:30
expect(urlUtility.getLocationHash).toHaveBeenCalled();
2018-12-13 13:39:08 +05:30
expect($note.toggleClass).toHaveBeenCalledWith('target', false);
2017-08-17 22:00:37 +05:30
});
2018-12-13 13:39:08 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
describe('renderNote', () => {
let notes;
let note;
let $notesList;
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
beforeEach(() => {
note = {
id: 1,
valid: true,
note: 'heya',
html: '<div>heya</div>',
};
2019-09-04 21:01:54 +05:30
$notesList = createSpyObj('$notesList', ['find', 'append']);
2018-12-13 13:39:08 +05:30
2019-09-04 21:01:54 +05:30
notes = createSpyObj('notes', [
2018-12-13 13:39:08 +05:30
'setupNewNote',
'refresh',
'collapseLongCommitList',
'updateNotesCount',
'putConflictEditWarningInPlace',
]);
2019-09-04 21:01:54 +05:30
notes.taskList = createSpyObj('tasklist', ['init']);
2018-12-13 13:39:08 +05:30
notes.note_ids = [];
notes.updatedNotesTrackingMap = {};
2019-09-04 21:01:54 +05:30
jest.spyOn(Notes, 'isNewNote');
jest.spyOn(Notes, 'isUpdatedNote');
jest.spyOn(Notes, 'animateAppendNote');
jest.spyOn(Notes, 'animateUpdateNote');
2018-12-13 13:39:08 +05:30
});
describe('when adding note', () => {
it('should call .animateAppendNote', () => {
2019-09-04 21:01:54 +05:30
Notes.isNewNote.mockReturnValueOnce(true);
2018-12-13 13:39:08 +05:30
Notes.prototype.renderNote.call(notes, note, null, $notesList);
expect(Notes.animateAppendNote).toHaveBeenCalledWith(note.html, $notesList);
2017-08-17 22:00:37 +05:30
});
2018-12-13 13:39:08 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
describe('when note was edited', () => {
it('should call .animateUpdateNote', () => {
2019-09-04 21:01:54 +05:30
Notes.isNewNote.mockReturnValueOnce(false);
Notes.isUpdatedNote.mockReturnValueOnce(true);
2018-12-13 13:39:08 +05:30
const $note = $('<div>');
2019-09-04 21:01:54 +05:30
$notesList.find.mockReturnValueOnce($note);
2018-12-13 13:39:08 +05:30
const $newNote = $(note.html);
2019-09-04 21:01:54 +05:30
Notes.animateUpdateNote.mockReturnValueOnce($newNote);
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
Notes.prototype.renderNote.call(notes, note, null, $notesList);
expect(Notes.animateUpdateNote).toHaveBeenCalledWith(note.html, $note);
expect(notes.setupNewNote).toHaveBeenCalledWith($newNote);
2017-08-17 22:00:37 +05:30
});
2018-12-13 13:39:08 +05:30
describe('while editing', () => {
it('should update textarea if nothing has been touched', () => {
2019-09-04 21:01:54 +05:30
Notes.isNewNote.mockReturnValueOnce(false);
Notes.isUpdatedNote.mockReturnValueOnce(true);
2018-12-13 13:39:08 +05:30
const $note = $(`<div class="is-editing">
<div class="original-note-content">initial</div>
<textarea class="js-note-text">initial</textarea>
</div>`);
2019-09-04 21:01:54 +05:30
$notesList.find.mockReturnValueOnce($note);
2017-08-17 22:00:37 +05:30
Notes.prototype.renderNote.call(notes, note, null, $notesList);
2018-12-13 13:39:08 +05:30
expect($note.find('.js-note-text').val()).toEqual(note.note);
2017-08-17 22:00:37 +05:30
});
2018-12-13 13:39:08 +05:30
it('should call .putConflictEditWarningInPlace', () => {
2019-09-04 21:01:54 +05:30
Notes.isNewNote.mockReturnValueOnce(false);
Notes.isUpdatedNote.mockReturnValueOnce(true);
2018-12-13 13:39:08 +05:30
const $note = $(`<div class="is-editing">
<div class="original-note-content">initial</div>
<textarea class="js-note-text">different</textarea>
</div>`);
2019-09-04 21:01:54 +05:30
$notesList.find.mockReturnValueOnce($note);
2018-12-13 13:39:08 +05:30
Notes.prototype.renderNote.call(notes, note, null, $notesList);
expect(notes.putConflictEditWarningInPlace).toHaveBeenCalledWith(note, $note);
2017-08-17 22:00:37 +05:30
});
});
});
2018-12-13 13:39:08 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
describe('isUpdatedNote', () => {
it('should consider same note text as the same', () => {
const result = Notes.isUpdatedNote(
{
note: 'initial',
},
$(`<div>
<div class="original-note-content">initial</div>
</div>`),
);
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
expect(result).toEqual(false);
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should consider same note with trailing newline as the same', () => {
const result = Notes.isUpdatedNote(
{
note: 'initial\n',
},
$(`<div>
<div class="original-note-content">initial\n</div>
</div>`),
);
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
expect(result).toEqual(false);
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should consider different notes as different', () => {
const result = Notes.isUpdatedNote(
{
note: 'foo',
},
$(`<div>
<div class="original-note-content">bar</div>
</div>`),
);
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
expect(result).toEqual(true);
});
});
describe('renderDiscussionNote', () => {
let discussionContainer;
let note;
let notes;
let $form;
let row;
beforeEach(() => {
note = {
html: '<li></li>',
discussion_html: '<div></div>',
discussion_id: 1,
discussion_resolvable: false,
diff_discussion_html: false,
};
2019-09-04 21:01:54 +05:30
$form = createSpyObj('$form', ['closest', 'find']);
2018-12-13 13:39:08 +05:30
$form.length = 1;
2019-09-04 21:01:54 +05:30
row = createSpyObj('row', ['prevAll', 'first', 'find']);
2018-12-13 13:39:08 +05:30
2019-09-04 21:01:54 +05:30
notes = createSpyObj('notes', ['isParallelView', 'updateNotesCount']);
2018-12-13 13:39:08 +05:30
notes.note_ids = [];
2019-09-04 21:01:54 +05:30
jest.spyOn(Notes, 'isNewNote');
jest.spyOn(Notes, 'animateAppendNote').mockImplementation();
Notes.isNewNote.mockReturnValue(true);
notes.isParallelView.mockReturnValue(false);
row.prevAll.mockReturnValue(row);
row.first.mockReturnValue(row);
row.find.mockReturnValue(row);
2017-08-17 22:00:37 +05:30
});
2018-12-13 13:39:08 +05:30
describe('Discussion root note', () => {
let body;
2017-08-17 22:00:37 +05:30
beforeEach(() => {
2019-09-04 21:01:54 +05:30
body = createSpyObj('body', ['attr']);
2018-12-13 13:39:08 +05:30
discussionContainer = { length: 0 };
2017-08-17 22:00:37 +05:30
2019-09-04 21:01:54 +05:30
$form.closest.mockReturnValueOnce(row).mockReturnValue($form);
$form.find.mockReturnValue(discussionContainer);
body.attr.mockReturnValue('');
2017-08-17 22:00:37 +05:30
});
2018-12-13 13:39:08 +05:30
it('should call Notes.animateAppendNote', () => {
Notes.prototype.renderDiscussionNote.call(notes, note, $form);
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
expect(Notes.animateAppendNote).toHaveBeenCalledWith(
note.discussion_html,
$('.main-notes-list'),
);
});
2018-03-17 18:26:18 +05:30
2018-12-13 13:39:08 +05:30
it('should append to row selected with line_code', () => {
$form.length = 0;
note.discussion_line_code = 'line_code';
note.diff_discussion_html = '<tr></tr>';
2018-03-17 18:26:18 +05:30
2018-12-13 13:39:08 +05:30
const line = document.createElement('div');
line.id = note.discussion_line_code;
document.body.appendChild(line);
2018-03-17 18:26:18 +05:30
2019-09-04 21:01:54 +05:30
// Override mocks for this single test
$form.closest.mockReset();
$form.closest.mockReturnValue($form);
2018-03-17 18:26:18 +05:30
2018-12-13 13:39:08 +05:30
Notes.prototype.renderDiscussionNote.call(notes, note, $form);
2018-03-17 18:26:18 +05:30
2018-12-13 13:39:08 +05:30
expect(line.nextSibling.outerHTML).toEqual(note.diff_discussion_html);
2017-08-17 22:00:37 +05:30
});
2018-12-13 13:39:08 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
describe('Discussion sub note', () => {
beforeEach(() => {
discussionContainer = { length: 1 };
2017-08-17 22:00:37 +05:30
2019-09-04 21:01:54 +05:30
$form.closest.mockReturnValueOnce(row).mockReturnValueOnce($form);
$form.find.mockReturnValue(discussionContainer);
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
Notes.prototype.renderDiscussionNote.call(notes, note, $form);
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should call Notes.animateAppendNote', () => {
expect(Notes.animateAppendNote).toHaveBeenCalledWith(note.html, discussionContainer);
2017-08-17 22:00:37 +05:30
});
});
2018-12-13 13:39:08 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
describe('animateAppendNote', () => {
let noteHTML;
let $notesList;
let $resultantNote;
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
beforeEach(() => {
noteHTML = '<div></div>';
2019-09-04 21:01:54 +05:30
$notesList = createSpyObj('$notesList', ['append']);
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
$resultantNote = Notes.animateAppendNote(noteHTML, $notesList);
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should have `fade-in-full` class', () => {
expect($resultantNote.hasClass('fade-in-full')).toEqual(true);
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should append note to the notes list', () => {
expect($notesList.append).toHaveBeenCalledWith($resultantNote);
2017-08-17 22:00:37 +05:30
});
2018-12-13 13:39:08 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
describe('animateUpdateNote', () => {
let noteHTML;
let $note;
let $updatedNote;
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
beforeEach(() => {
noteHTML = '<div></div>';
2019-09-04 21:01:54 +05:30
$note = createSpyObj('$note', ['replaceWith']);
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
$updatedNote = Notes.animateUpdateNote(noteHTML, $note);
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should have `fade-in` class', () => {
expect($updatedNote.hasClass('fade-in')).toEqual(true);
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should call replaceWith on $note', () => {
expect($note.replaceWith).toHaveBeenCalledWith($updatedNote);
2017-08-17 22:00:37 +05:30
});
2018-12-13 13:39:08 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
describe('putEditFormInPlace', () => {
it('should call GLForm with GFM parameter passed through', () => {
const notes = new Notes('', []);
const $el = $(`
<div>
<form></form>
</div>
`);
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
notes.putEditFormInPlace($el);
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
expect(notes.glForm.enableGFM).toBeTruthy();
2017-09-10 17:25:29 +05:30
});
2018-12-13 13:39:08 +05:30
});
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
describe('postComment & updateComment', () => {
const sampleComment = 'foo';
const note = {
id: 1234,
html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
<div class="note-text">${sampleComment}</div>
</li>`,
note: sampleComment,
valid: true,
};
2019-09-04 21:01:54 +05:30
let notes;
2018-12-13 13:39:08 +05:30
let $form;
let $notesContainer;
function mockNotesPost() {
2019-09-04 21:01:54 +05:30
mockAxios.onPost(NOTES_POST_PATH).reply(200, note);
2018-12-13 13:39:08 +05:30
}
function mockNotesPostError() {
2019-09-04 21:01:54 +05:30
mockAxios.onPost(NOTES_POST_PATH).networkError();
2018-12-13 13:39:08 +05:30
}
beforeEach(() => {
2019-09-04 21:01:54 +05:30
notes = new Notes('', []);
2018-12-13 13:39:08 +05:30
window.gon.current_username = 'root';
window.gon.current_user_fullname = 'Administrator';
$form = $('form.js-main-target-form');
$notesContainer = $('ul.main-notes-list');
$form.find('textarea.js-note-text').val(sampleComment);
});
2018-03-17 18:26:18 +05:30
2018-12-13 13:39:08 +05:30
it('should show placeholder note while new comment is being posted', () => {
mockNotesPost();
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
$('.js-comment-button').click();
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
expect($notesContainer.find('.note.being-posted').length).toBeGreaterThan(0);
});
2018-03-17 18:26:18 +05:30
2022-04-04 11:22:00 +05:30
it('should remove placeholder note when new comment is done posting', async () => {
2018-12-13 13:39:08 +05:30
mockNotesPost();
2018-03-17 18:26:18 +05:30
2018-12-13 13:39:08 +05:30
$('.js-comment-button').click();
2017-08-17 22:00:37 +05:30
2022-04-04 11:22:00 +05:30
await waitForPromises();
expect($notesContainer.find('.note.being-posted').length).toEqual(0);
2018-12-13 13:39:08 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
describe('postComment', () => {
2022-06-21 17:19:12 +05:30
it('disables the submit button', async () => {
2018-12-13 13:39:08 +05:30
const $submitButton = $form.find('.js-comment-submit-button');
2018-03-17 18:26:18 +05:30
2018-12-13 13:39:08 +05:30
expect($submitButton).not.toBeDisabled();
const dummyEvent = {
preventDefault() {},
target: $submitButton,
};
2019-09-04 21:01:54 +05:30
mockAxios.onPost(NOTES_POST_PATH).replyOnce(() => {
2018-12-13 13:39:08 +05:30
expect($submitButton).toBeDisabled();
return [200, note];
2018-03-17 18:26:18 +05:30
});
2017-08-17 22:00:37 +05:30
2022-06-21 17:19:12 +05:30
await notes.postComment(dummyEvent);
expect($submitButton).not.toBeDisabled();
2018-05-09 12:01:36 +05:30
});
2018-12-13 13:39:08 +05:30
});
2018-05-09 12:01:36 +05:30
2022-04-04 11:22:00 +05:30
it('should show actual note element when new comment is done posting', async () => {
2018-12-13 13:39:08 +05:30
mockNotesPost();
2018-03-17 18:26:18 +05:30
2018-12-13 13:39:08 +05:30
$('.js-comment-button').click();
2017-08-17 22:00:37 +05:30
2022-04-04 11:22:00 +05:30
await waitForPromises();
expect($notesContainer.find(`#note_${note.id}`).length).toBeGreaterThan(0);
2018-12-13 13:39:08 +05:30
});
2017-08-17 22:00:37 +05:30
2022-04-04 11:22:00 +05:30
it('should reset Form when new comment is done posting', async () => {
2018-12-13 13:39:08 +05:30
mockNotesPost();
2018-03-17 18:26:18 +05:30
2018-12-13 13:39:08 +05:30
$('.js-comment-button').click();
2017-08-17 22:00:37 +05:30
2022-04-04 11:22:00 +05:30
await waitForPromises();
expect($form.find('textarea.js-note-text').val()).toEqual('');
2018-12-13 13:39:08 +05:30
});
2017-08-17 22:00:37 +05:30
2022-04-04 11:22:00 +05:30
it('should show flash error message when new comment failed to be posted', async () => {
2018-12-13 13:39:08 +05:30
mockNotesPostError();
2019-09-04 21:01:54 +05:30
jest.spyOn(notes, 'addFlash');
2018-03-17 18:26:18 +05:30
2018-12-13 13:39:08 +05:30
$('.js-comment-button').click();
2017-08-17 22:00:37 +05:30
2022-04-04 11:22:00 +05:30
await waitForPromises();
expect(notes.addFlash).toHaveBeenCalled();
// JSDom doesn't support the :visible selector yet
expect(notes.flashContainer.style.display).not.toBe('none');
2018-12-13 13:39:08 +05:30
});
});
2017-08-17 22:00:37 +05:30
2020-07-28 23:09:34 +05:30
describe('postComment with quick actions', () => {
2018-12-13 13:39:08 +05:30
const sampleComment = '/assign @root\n/award :100:';
const note = {
commands_changes: {
assignee_id: 1,
emoji_award: '100',
},
errors: {
commands_only: ['Commands applied'],
},
valid: false,
};
let $form;
let $notesContainer;
beforeEach(() => {
2022-07-16 23:28:13 +05:30
loadHTMLFixture('commit/show.html');
2019-09-04 21:01:54 +05:30
mockAxios.onPost(NOTES_POST_PATH).reply(200, note);
2018-12-13 13:39:08 +05:30
2019-09-04 21:01:54 +05:30
new Notes('', []);
2018-12-13 13:39:08 +05:30
window.gon.current_username = 'root';
window.gon.current_user_fullname = 'Administrator';
gl.awardsHandler = {
addAwardToEmojiBar: () => {},
scrollToAwards: () => {},
};
gl.GfmAutoComplete = {
dataSources: {
commands: '/root/test-project/autocomplete_sources/commands',
2017-09-10 17:25:29 +05:30
},
};
2018-12-13 13:39:08 +05:30
$form = $('form.js-main-target-form');
$notesContainer = $('ul.main-notes-list');
$form.find('textarea.js-note-text').val(sampleComment);
});
2017-09-10 17:25:29 +05:30
2022-04-04 11:22:00 +05:30
it('should remove quick action placeholder when comment with quick actions is done posting', async () => {
2019-09-04 21:01:54 +05:30
jest.spyOn(gl.awardsHandler, 'addAwardToEmojiBar');
2018-12-13 13:39:08 +05:30
$('.js-comment-button').click();
2017-09-10 17:25:29 +05:30
2020-07-28 23:09:34 +05:30
expect($notesContainer.find('.note.being-posted').length).toEqual(1); // Placeholder shown
2018-03-17 18:26:18 +05:30
2022-04-04 11:22:00 +05:30
await waitForPromises();
expect($notesContainer.find('.note.being-posted').length).toEqual(0); // Placeholder removed
2020-07-28 23:09:34 +05:30
});
});
describe('postComment with slash when quick actions are not supported', () => {
const sampleComment = '/assign @root';
let $form;
let $notesContainer;
beforeEach(() => {
const note = {
id: 1234,
html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
<div class="note-text">${sampleComment}</div>
</li>`,
note: sampleComment,
valid: true,
};
mockAxios.onPost(NOTES_POST_PATH).reply(200, note);
new Notes('', []);
$form = $('form.js-main-target-form');
$notesContainer = $('ul.main-notes-list');
$form.find('textarea.js-note-text').val(sampleComment);
});
2022-04-04 11:22:00 +05:30
it('should show message placeholder including lines starting with slash', async () => {
2020-07-28 23:09:34 +05:30
$('.js-comment-button').click();
expect($notesContainer.find('.note.being-posted').length).toEqual(1); // Placeholder shown
expect($notesContainer.find('.note-body p').text()).toEqual(sampleComment); // No quick action processing
2022-04-04 11:22:00 +05:30
await waitForPromises();
expect($notesContainer.find('.note.being-posted').length).toEqual(0); // Placeholder removed
2017-09-10 17:25:29 +05:30
});
2018-12-13 13:39:08 +05:30
});
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
describe('update comment with script tags', () => {
const sampleComment = '<script></script>';
const updatedComment = '<script></script>';
const note = {
id: 1234,
html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
<div class="note-text">${sampleComment}</div>
</li>`,
note: sampleComment,
valid: true,
};
let $form;
let $notesContainer;
beforeEach(() => {
2019-09-04 21:01:54 +05:30
mockAxios.onPost(NOTES_POST_PATH).reply(200, note);
2018-12-13 13:39:08 +05:30
2019-09-04 21:01:54 +05:30
new Notes('', []);
2018-12-13 13:39:08 +05:30
window.gon.current_username = 'root';
window.gon.current_user_fullname = 'Administrator';
$form = $('form.js-main-target-form');
$notesContainer = $('ul.main-notes-list');
$form.find('textarea.js-note-text').html(sampleComment);
});
2017-08-17 22:00:37 +05:30
2022-04-04 11:22:00 +05:30
it('should not render a script tag', async () => {
2018-12-13 13:39:08 +05:30
$('.js-comment-button').click();
2018-03-17 18:26:18 +05:30
2022-04-04 11:22:00 +05:30
await waitForPromises();
2017-08-17 22:00:37 +05:30
2022-04-04 11:22:00 +05:30
const $noteEl = $notesContainer.find(`#note_${note.id}`);
$noteEl.find('.js-note-edit').click();
$noteEl.find('textarea.js-note-text').html(updatedComment);
$noteEl.find('.js-comment-save-button').click();
2017-08-17 22:00:37 +05:30
2022-04-04 11:22:00 +05:30
const $updatedNoteEl = $notesContainer
.find(`#note_${note.id}`)
.find('.js-task-list-container');
2018-03-17 18:26:18 +05:30
2022-04-04 11:22:00 +05:30
expect($updatedNoteEl.find('.note-text').text().trim()).toEqual('');
2017-08-17 22:00:37 +05:30
});
2018-12-13 13:39:08 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
describe('getFormData', () => {
let $form;
let sampleComment;
2019-09-04 21:01:54 +05:30
let notes;
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
beforeEach(() => {
2019-09-04 21:01:54 +05:30
notes = new Notes('', []);
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
$form = $('form');
sampleComment = 'foobar';
});
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
it('should return form metadata object from form reference', () => {
$form.find('textarea.js-note-text').val(sampleComment);
2019-09-04 21:01:54 +05:30
const { formData, formContent, formAction } = notes.getFormData($form);
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
expect(formData.indexOf(sampleComment)).toBeGreaterThan(-1);
expect(formContent).toEqual(sampleComment);
expect(formAction).toEqual($form.attr('action'));
});
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
it('should return form metadata with sanitized formContent from form reference', () => {
sampleComment = '<script>alert("Boom!");</script>';
$form.find('textarea.js-note-text').val(sampleComment);
2017-09-10 17:25:29 +05:30
2019-09-04 21:01:54 +05:30
const { formContent } = notes.getFormData($form);
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
expect(formContent).toEqual('&lt;script&gt;alert(&quot;Boom!&quot;);&lt;/script&gt;');
2017-08-17 22:00:37 +05:30
});
2018-12-13 13:39:08 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
describe('hasQuickActions', () => {
2019-09-04 21:01:54 +05:30
let notes;
2018-12-13 13:39:08 +05:30
beforeEach(() => {
2019-09-04 21:01:54 +05:30
notes = new Notes('', []);
2018-12-13 13:39:08 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should return true when comment begins with a quick action', () => {
const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign Merging this';
2019-09-04 21:01:54 +05:30
const hasQuickActions = notes.hasQuickActions(sampleComment);
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
expect(hasQuickActions).toBeTruthy();
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should return false when comment does NOT begin with a quick action', () => {
const sampleComment = 'Hey, /unassign Merging this';
2019-09-04 21:01:54 +05:30
const hasQuickActions = notes.hasQuickActions(sampleComment);
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
expect(hasQuickActions).toBeFalsy();
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should return false when comment does NOT have any quick actions', () => {
const sampleComment = 'Looking good, Awesome!';
2019-09-04 21:01:54 +05:30
const hasQuickActions = notes.hasQuickActions(sampleComment);
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
expect(hasQuickActions).toBeFalsy();
2017-08-17 22:00:37 +05:30
});
2018-12-13 13:39:08 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
describe('stripQuickActions', () => {
it('should strip quick actions from the comment which begins with a quick action', () => {
2019-09-04 21:01:54 +05:30
const notes = new Notes();
2018-12-13 13:39:08 +05:30
const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign Merging this';
2019-09-04 21:01:54 +05:30
const stripedComment = notes.stripQuickActions(sampleComment);
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
expect(stripedComment).toBe('');
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should strip quick actions from the comment but leaves plain comment if it is present', () => {
2019-09-04 21:01:54 +05:30
const notes = new Notes();
2018-12-13 13:39:08 +05:30
const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign\nMerging this';
2019-09-04 21:01:54 +05:30
const stripedComment = notes.stripQuickActions(sampleComment);
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
expect(stripedComment).toBe('Merging this');
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should NOT strip string that has slashes within', () => {
2019-09-04 21:01:54 +05:30
const notes = new Notes();
2018-12-13 13:39:08 +05:30
const sampleComment = 'http://127.0.0.1:3000/root/gitlab-shell/issues/1';
2019-09-04 21:01:54 +05:30
const stripedComment = notes.stripQuickActions(sampleComment);
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
expect(stripedComment).toBe(sampleComment);
2017-08-17 22:00:37 +05:30
});
2018-12-13 13:39:08 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
describe('getQuickActionDescription', () => {
const availableQuickActions = [
{ name: 'close', description: 'Close this issue', params: [] },
{ name: 'title', description: 'Change title', params: [{}] },
{ name: 'estimate', description: 'Set time estimate', params: [{}] },
];
2019-09-04 21:01:54 +05:30
let notes;
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
beforeEach(() => {
2019-09-04 21:01:54 +05:30
notes = new Notes();
2018-12-13 13:39:08 +05:30
});
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
it('should return executing quick action description when note has single quick action', () => {
const sampleComment = '/close';
2017-09-10 17:25:29 +05:30
2019-09-04 21:01:54 +05:30
expect(notes.getQuickActionDescription(sampleComment, availableQuickActions)).toBe(
2018-12-13 13:39:08 +05:30
'Applying command to close this issue',
);
});
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
it('should return generic multiple quick action description when note has multiple quick actions', () => {
const sampleComment = '/close\n/title [Duplicate] Issue foobar';
2019-09-04 21:01:54 +05:30
expect(notes.getQuickActionDescription(sampleComment, availableQuickActions)).toBe(
2018-12-13 13:39:08 +05:30
'Applying multiple commands',
);
2017-09-10 17:25:29 +05:30
});
2018-12-13 13:39:08 +05:30
it('should return generic quick action description when available quick actions list is not populated', () => {
const sampleComment = '/close\n/title [Duplicate] Issue foobar';
2017-08-17 22:00:37 +05:30
2019-09-04 21:01:54 +05:30
expect(notes.getQuickActionDescription(sampleComment)).toBe('Applying command');
2018-12-13 13:39:08 +05:30
});
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
describe('createPlaceholderNote', () => {
const sampleComment = 'foobar';
const uniqueId = 'b1234-a4567';
const currentUsername = 'root';
const currentUserFullname = 'Administrator';
const currentUserAvatar = 'avatar_url';
2019-09-04 21:01:54 +05:30
let notes;
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
beforeEach(() => {
2019-09-04 21:01:54 +05:30
notes = new Notes('', []);
2018-12-13 13:39:08 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should return constructed placeholder element for regular note based on form contents', () => {
2019-09-04 21:01:54 +05:30
const $tempNote = notes.createPlaceholderNote({
2018-12-13 13:39:08 +05:30
formContent: sampleComment,
uniqueId,
isDiscussionNote: false,
currentUsername,
currentUserFullname,
currentUserAvatar,
});
const $tempNoteHeader = $tempNote.find('.note-header');
expect($tempNote.prop('nodeName')).toEqual('LI');
expect($tempNote.attr('id')).toEqual(uniqueId);
expect($tempNote.hasClass('being-posted')).toBeTruthy();
expect($tempNote.hasClass('fade-in-half')).toBeTruthy();
2019-09-04 21:01:54 +05:30
$tempNote.find('.timeline-icon > a, .note-header-info > a').each((i, el) => {
expect(el.getAttribute('href')).toEqual(`/${currentUsername}`);
2018-12-13 13:39:08 +05:30
});
expect($tempNote.find('.timeline-icon .avatar').attr('src')).toEqual(currentUserAvatar);
expect($tempNote.find('.timeline-content').hasClass('discussion')).toBeFalsy();
2021-03-08 18:12:59 +05:30
expect($tempNoteHeader.find('.d-none.d-sm-inline-block').text().trim()).toEqual(
currentUserFullname,
);
expect($tempNoteHeader.find('.note-headline-light').text().trim()).toEqual(
`@${currentUsername}`,
);
expect($tempNote.find('.note-body .note-text p').text().trim()).toEqual(sampleComment);
2018-12-13 13:39:08 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should return constructed placeholder element for discussion note based on form contents', () => {
2019-09-04 21:01:54 +05:30
const $tempNote = notes.createPlaceholderNote({
2018-12-13 13:39:08 +05:30
formContent: sampleComment,
uniqueId,
isDiscussionNote: true,
currentUsername,
currentUserFullname,
2017-09-10 17:25:29 +05:30
});
2018-12-13 13:39:08 +05:30
expect($tempNote.prop('nodeName')).toEqual('LI');
expect($tempNote.find('.timeline-content').hasClass('discussion')).toBeTruthy();
2017-09-10 17:25:29 +05:30
});
2018-12-13 13:39:08 +05:30
it('should return a escaped user name', () => {
const currentUserFullnameXSS = 'Foo <script>alert("XSS")</script>';
2019-09-04 21:01:54 +05:30
const $tempNote = notes.createPlaceholderNote({
2018-12-13 13:39:08 +05:30
formContent: sampleComment,
uniqueId,
isDiscussionNote: false,
currentUsername,
currentUserFullname: currentUserFullnameXSS,
currentUserAvatar,
});
const $tempNoteHeader = $tempNote.find('.note-header');
2021-03-08 18:12:59 +05:30
expect($tempNoteHeader.find('.d-none.d-sm-inline-block').text().trim()).toEqual(
'Foo &lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;',
);
2018-12-13 13:39:08 +05:30
});
});
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
describe('createPlaceholderSystemNote', () => {
const sampleCommandDescription = 'Applying command to close this issue';
const uniqueId = 'b1234-a4567';
2019-09-04 21:01:54 +05:30
let notes;
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
beforeEach(() => {
2019-09-04 21:01:54 +05:30
notes = new Notes('', []);
2018-12-13 13:39:08 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should return constructed placeholder element for system note based on form contents', () => {
2019-09-04 21:01:54 +05:30
const $tempNote = notes.createPlaceholderSystemNote({
2018-12-13 13:39:08 +05:30
formContent: sampleCommandDescription,
uniqueId,
});
expect($tempNote.prop('nodeName')).toEqual('LI');
expect($tempNote.attr('id')).toEqual(uniqueId);
expect($tempNote.hasClass('being-posted')).toBeTruthy();
expect($tempNote.hasClass('fade-in-half')).toBeTruthy();
2021-03-08 18:12:59 +05:30
expect($tempNote.find('.timeline-content i').text().trim()).toEqual(sampleCommandDescription);
2017-09-10 17:25:29 +05:30
});
2018-12-13 13:39:08 +05:30
});
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
describe('appendFlash', () => {
it('shows a flash message', () => {
2019-09-04 21:01:54 +05:30
const notes = new Notes('', []);
notes.addFlash('Error message', FLASH_TYPE_ALERT, notes.parentTimeline.get(0));
2017-09-10 17:25:29 +05:30
2019-09-04 21:01:54 +05:30
const flash = $('.flash-alert')[0];
expect(document.contains(flash)).toBe(true);
expect(flash.parentNode.style.display).toBe('block');
2017-09-10 17:25:29 +05:30
});
2018-12-13 13:39:08 +05:30
});
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
describe('clearFlash', () => {
beforeEach(() => {
$(document).off('ajax:success');
});
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
it('hides visible flash message', () => {
2019-09-04 21:01:54 +05:30
const notes = new Notes('', []);
notes.addFlash('Error message 1', FLASH_TYPE_ALERT, notes.parentTimeline.get(0));
const flash = $('.flash-alert')[0];
notes.clearFlash();
expect(flash.parentNode.style.display).toBe('none');
expect(notes.flashContainer).toBeNull();
2017-08-17 22:00:37 +05:30
});
});
2018-12-13 13:39:08 +05:30
});