summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/notes.js6
-rw-r--r--doc/development/fe_guide/testing.md62
-rw-r--r--spec/javascripts/notes_spec.js41
3 files changed, 106 insertions, 3 deletions
diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js
index 67df1c0c4d7..62a46733cc4 100644
--- a/app/assets/javascripts/notes.js
+++ b/app/assets/javascripts/notes.js
@@ -578,12 +578,12 @@ const normalizeNewlines = function(str) {
Updates the current note field.
*/
- Notes.prototype.updateNote = function(_xhr, noteEntity, _status) {
+ Notes.prototype.updateNote = function(noteEntity, $targetNote) {
var $noteEntityEl, $note_li;
// Convert returned HTML to a jQuery object so we can modify it further
$noteEntityEl = $(noteEntity.html);
$noteEntityEl.addClass('fade-in-full');
- this.revertNoteEditForm();
+ this.revertNoteEditForm($targetNote);
gl.utils.localTimeAgo($('.js-timeago', $noteEntityEl));
$noteEntityEl.renderGFM();
$noteEntityEl.find('.js-task-list-container').taskList('enable');
@@ -1404,7 +1404,7 @@ const normalizeNewlines = function(str) {
gl.utils.ajaxPost(formAction, formData)
.then((note) => {
// Submission successful! render final note element
- this.updateNote(null, note, null);
+ this.updateNote(note, $editingNote);
})
.fail(() => {
// Submission failed, revert back to original note
diff --git a/doc/development/fe_guide/testing.md b/doc/development/fe_guide/testing.md
index 5852cac2aa5..5c6bdc97ef6 100644
--- a/doc/development/fe_guide/testing.md
+++ b/doc/development/fe_guide/testing.md
@@ -68,6 +68,68 @@ describe('.methodName', () => {
});
});
```
+#### Testing Promises
+
+When testing Promises you should always make sure that the test is asynchronous and rejections are handled.
+Your Promise chain should therefore end with a call of the `done` callback and `done.fail` in case an error occurred.
+
+```javascript
+/// Good
+it('tests a promise', (done) => {
+ promise
+ .then((data) => {
+ expect(data).toBe(asExpected);
+ })
+ .then(done)
+ .catch(done.fail);
+});
+
+/// Good
+it('tests a promise rejection', (done) => {
+ promise
+ .catch((error) => {
+ expect(error).toBe(expectedError);
+ })
+ .then(done)
+ .catch(done.fail);
+});
+
+/// Bad (missing done callback)
+it('tests a promise', () => {
+ promise
+ .then((data) => {
+ expect(data).toBe(asExpected);
+ })
+});
+
+/// Bad (missing catch)
+it('tests a promise', (done) => {
+ promise
+ .then((data) => {
+ expect(data).toBe(asExpected);
+ })
+ .then(done)
+});
+
+/// Bad (use done.fail in asynchronous tests)
+it('tests a promise', (done) => {
+ promise
+ .then((data) => {
+ expect(data).toBe(asExpected);
+ })
+ .then(done)
+ .catch(fail)
+});
+
+/// Bad (missing catch)
+it('tests a promise rejection', (done) => {
+ promise
+ .catch((error) => {
+ expect(error).toBe(expectedError);
+ })
+ .then(done)
+});
+```
#### Stubbing
diff --git a/spec/javascripts/notes_spec.js b/spec/javascripts/notes_spec.js
index 7f12dea5277..d3494aaa94f 100644
--- a/spec/javascripts/notes_spec.js
+++ b/spec/javascripts/notes_spec.js
@@ -79,6 +79,47 @@ import '~/notes';
});
});
+ describe('updateNote', () => {
+ let sampleComment;
+ let noteEntity;
+ let $form;
+ let $notesContainer;
+
+ beforeEach(() => {
+ this.notes = new Notes('', []);
+ window.gon.current_username = 'root';
+ window.gon.current_user_fullname = 'Administrator';
+ sampleComment = 'foo';
+ 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
+ };
+ $form = $('form.js-main-target-form');
+ $notesContainer = $('ul.main-notes-list');
+ $form.find('textarea.js-note-text').val(sampleComment);
+ });
+
+ it('updates note and resets edit form', () => {
+ const deferred = $.Deferred();
+ spyOn($, 'ajax').and.returnValue(deferred.promise());
+ spyOn(this.notes, 'revertNoteEditForm');
+
+ $('.js-comment-button').click();
+ deferred.resolve(noteEntity);
+
+ const $targetNote = $notesContainer.find(`#note_${noteEntity.id}`);
+ const updatedNote = Object.assign({}, noteEntity);
+ updatedNote.note = 'bar';
+ this.notes.updateNote(updatedNote, $targetNote);
+
+ expect(this.notes.revertNoteEditForm).toHaveBeenCalledWith($targetNote);
+ });
+ });
+
describe('renderNote', () => {
let notes;
let note;