UNPKG

jquery-comments

Version:

jQuery plugin for implementing an out-of-the-box commenting solution to any web application with an existing backend

837 lines (655 loc) 34.5 kB
describe('Basic features', function() { var comments; beforeEach(function() { var commentsContainer = $('<div/>'); commentsContainer.comments({ spinnerImageURL: '../img/ajax-loader.gif', profilePictureURL: 'https://app.viima.com/static/media/user_profiles/user-icon.png', roundProfilePictures: true, textareaRows: 1, textareaMaxRows: 4, getComments: function(success, error) { success(commentsArray); }, postComment: function(data, success, error) { setTimeout(function() { success(data); }, 10); }, putComment: function(data, success, error) { setTimeout(function() { success(data); }, 10); }, deleteComment: function(data, success, error) { setTimeout(function() { success(); }, 10); }, upvoteComment: function(data, success, error) { setTimeout(function() { success(data); }, 10); } }); // Append element to DOM $('body').append(commentsContainer); // Save the instance to global scope comments = $('.jquery-comments').data().comments; }); it('Should call the required functions upon refresh', function() { spyOn(comments, 'render').andCallThrough(); spyOn(comments, 'fetchDataAndRender').andCallThrough(); spyOn(comments, 'createCommentModel').andCallThrough(); spyOn(comments, 'addCommentToDataModel').andCallThrough(); spyOn(comments, 'sortComments').andCallThrough(); comments.fetchDataAndRender(); expect(comments.render.calls.length).toEqual(1); expect(comments.fetchDataAndRender.calls.length).toEqual(1); expect(comments.createCommentModel.calls.length).toEqual(10); expect(comments.addCommentToDataModel.calls.length).toEqual(10); expect(comments.sortComments.calls.length).toBeGreaterThan(1); }); it('Should have rendered the comments', function() { var commentElements = $('li.comment'); expect(commentElements.length).toEqual(10); commentElements.each(function(index, commentEl) { checkCommentElementData($(commentEl)); }); checkOrder($('ul#comment-list > li.comment'), [1,3,2]); // Check reply to -fields expect($('li.comment[data-id=8] .name .reply-to').text()).toBe('Jack Hemsworth'); expect($('li.comment[data-id=9] .name .reply-to').text()).toBe('You'); expect($('li.comment[data-id=5] .name .reply-to').text()).toBe('Todd Brown'); expect($('li.comment[data-id=10] .name .reply-to').text()).toBe('Bryan Connery'); // Check that other comments do not have the field $('li.comment').each(function(index, el) { var el = $(el); if([8,9,5,10].indexOf(el.data().model.id) == -1) { expect(el.find('.name').first().find('.reply-to').length).toBe(0); } }); // Check edited timestamps var editedDateFromUI = new Date($('li.comment[data-id=9] .content .edited').attr('data-original')); compareDates(editedDateFromUI, new Date('1/10/2015')); // Check that other comments do not have the field $('li.comment').each(function(index, el) { var el = $(el); if([9].indexOf(el.data().model.id) == -1) { expect(el.find('.content').first().find('.edited').length).toBe(0); } }); }); it('Should have appended the child comments under their outermost parent', function() { expect($('#comment-list > li.comment').length).toBe(3); checkOrder($('li.comment[data-id=1] .child-comments > li.comment'), [6,7,8,9,10]); checkOrder($('li.comment[data-id=2] .child-comments > li.comment'), []); checkOrder($('li.comment[data-id=3] .child-comments > li.comment'), [4,5]); }); it('Should sort the main level comments wihtout affecting the order of child comments', function() { $('li[data-sort-key="popularity"]').click(); checkOrder($('#comment-list > li.comment'), [1,3,2]); checkOrder($('li.comment[data-id=1] .child-comments > li.comment'), [6,7,8,9,10]); $('li[data-sort-key="newest"]').click(); checkOrder($('#comment-list > li.comment'), [3,2,1]); checkOrder($('li.comment[data-id=1] .child-comments > li.comment'), [6,7,8,9,10]); $('li[data-sort-key="oldest"]').click(); checkOrder($('#comment-list > li.comment'), [1,2,3]); checkOrder($('li.comment[data-id=1] .child-comments > li.comment'), [6,7,8,9,10]); }); it('Should be able to toggle all replies', function() { var toggleAll = $('li.comment[data-id=1]').find('.child-comments li.toggle-all'); expect(toggleAll.length).toBe(1); expect(toggleAll.text()).toBe('View all 5 replies'); expect($('li.comment[data-id=1] li.comment:visible').length).toBe(2); // Show all replies toggleAll.click(); expect(toggleAll.text()).toBe('Hide replies'); expect($('li.comment[data-id=1] li.comment:visible').length).toBe(5); // Hide replies toggleAll.click(); expect(toggleAll.text()).toBe('View all 5 replies'); expect($('li.comment[data-id=1] li.comment:visible').length).toBe(2); }); describe('Commenting', function() { var mainCommentingField; var mainTextarea; var lineHeight; beforeEach(function() { mainCommentingField = $('.commenting-field.main'); mainTextarea = mainCommentingField.find('.textarea'); lineHeight = parseInt(mainTextarea.css('line-height')); }); it('Should adjust the height of commenting field dynamically', function() { // Should have 1 row expect(mainTextarea.outerHeight()).toBeLessThan(2*lineHeight); // Should have 2 rows mainTextarea.trigger('click'); expect(mainTextarea.outerHeight()).toBeGreaterThan(2*lineHeight); expect(mainTextarea.outerHeight()).toBeLessThan(3*lineHeight); // Should have 2 rows mainTextarea.append($('<div>row 1</div>')).trigger('input'); mainTextarea.append($('<div>row 2</div>')).trigger('input'); expect(mainTextarea.outerHeight()).toBeGreaterThan(2*lineHeight); expect(mainTextarea.outerHeight()).toBeLessThan(3*lineHeight); // Should have 3 rows mainTextarea.append($('<div>row 3</div>')).trigger('input'); expect(mainTextarea.outerHeight()).toBeGreaterThan(3*lineHeight); expect(mainTextarea.outerHeight()).toBeLessThan(4*lineHeight); // Should have 4 rows mainTextarea.append($('<div>row 4</div>')).trigger('input'); expect(mainTextarea.outerHeight()).toBeGreaterThan(4*lineHeight); expect(mainTextarea.outerHeight()).toBeLessThan(5*lineHeight); // Should have 4 rows as it's the max value mainTextarea.append($('<div>row 5</div>')).trigger('input'); expect(mainTextarea.outerHeight()).toBeGreaterThan(4*lineHeight); expect(mainTextarea.outerHeight()).toBeLessThan(5*lineHeight); // Should have 3 rows mainTextarea.find('div').last().remove(); mainTextarea.find('div').last().remove(); mainTextarea.trigger('input'); expect(mainTextarea.outerHeight()).toBeGreaterThan(3*lineHeight); expect(mainTextarea.outerHeight()).toBeLessThan(4*lineHeight); // Should have 2 rows mainTextarea.find('div').remove(); mainTextarea.trigger('input'); expect(mainTextarea.outerHeight()).toBeGreaterThan(2*lineHeight); expect(mainTextarea.outerHeight()).toBeLessThan(3*lineHeight); // Should have 1 row mainCommentingField.find('.close').click(); expect(mainTextarea.outerHeight()).toBeLessThan(2*lineHeight); }); it('Should enable control row on click', function() { var controlRow = mainCommentingField.find('.control-row');; // Show on click expect(controlRow.is(':visible')).toBe(false); mainTextarea.trigger('click'); expect(controlRow.is(':visible')).toBe(true); // Hide when clicking close icon mainCommentingField.find('.close').click(); expect(controlRow.is(':visible')).toBe(false); }); it('Should enable send button when texarea is not empty', function() { var sendButton = mainCommentingField.find('.send'); expect(sendButton.is(':visible')).toBe(false); expect(sendButton.hasClass('enabled')).toBe(false); // Show on click mainTextarea.trigger('click'); expect(sendButton.is(':visible')).toBe(true); expect(sendButton.hasClass('enabled')).toBe(false); // Enable when content mainTextarea.append($('<div>row 1</div>')).trigger('input'); expect(sendButton.is(':visible')).toBe(true); expect(sendButton.hasClass('enabled')).toBe(true); // Disable when no content mainTextarea.empty().trigger('input'); expect(sendButton.is(':visible')).toBe(true); expect(sendButton.hasClass('enabled')).toBe(false); // Hide when clicking close icon mainCommentingField.find('.close').click(); expect(sendButton.is(':visible')).toBe(false); expect(sendButton.hasClass('enabled')).toBe(false); }); it('Should able to add a new main level comment', function() { var newCommentText = 'New main level comment\nwith a new line'; mainTextarea.html(newCommentText).trigger('input'); var commentCount = comments.getComments().length; wait(function() { return comments.getComments().length == commentCount + 1; }); mainCommentingField.find('.send').trigger('click'); run(function() { // New comment should always be placed first initially var commentEl = $('li.comment').first(); var idOfNewComment = commentEl.data().id; expect(commentEl.find('.content').text()).toBe(newCommentText); expect(commentEl.hasClass('by-current-user')).toBe(true); checkCommentElementData(commentEl); // Check that sorting works also with the new comment checkOrder($('#comment-list > li.comment'), [idOfNewComment, 1,3,2]); $('li[data-sort-key="oldest"]').click(); checkOrder($('#comment-list > li.comment'), [1,2,3,idOfNewComment]); $('li[data-sort-key="newest"]').click(); checkOrder($('#comment-list > li.comment'), [idOfNewComment,3,2,1]); }); }); }); describe('Replying', function() { var mostPopularComment; beforeEach(function() { mostPopularComment = $('li.comment[data-id=1]'); }); it('Should not show the reply field by default', function() { var replyField = mostPopularComment.find('.commenting-field'); expect(replyField.length).toBe(0); }); it('Should be able to reply', function() { mostPopularComment.find('.reply').first().click(); var replyField = mostPopularComment.find('.commenting-field'); expect(replyField.length).toBe(1); expect(replyField.find('.reply-to-badge').length).toBe(0); // Check that the field is last child var lastChild = mostPopularComment.find('.child-comments').children().last(); expect(lastChild[0]).toBe(replyField[0]); var replyText = 'This is a reply\nwith a new line'; replyField.find('.textarea').append(replyText).trigger('input'); var commentCount = comments.getComments().length; wait(function() { return comments.getComments().length == commentCount + 1; }); replyField.find('.send').trigger('click'); run(function() { // New reply should always be placed last var commentEl = mostPopularComment.find('li.comment').last(); var idOfNewComment = commentEl.data().id; expect(commentEl.find('.content').text()).toBe(replyText); expect(commentEl.hasClass('by-current-user')).toBe(true); checkCommentElementData(commentEl); // Check position checkOrder(mostPopularComment.find('li.comment'), [6,7,8,9,10,idOfNewComment]); var toggleAllText = mostPopularComment.find('li.toggle-all').text(); expect(toggleAllText).toBe('View all 6 replies'); expect(mostPopularComment.find('li.comment:visible').length).toBe(2); }); }); it('Should close the reply field when clicking the close icon', function() { mostPopularComment.find('.reply').first().click(); var replyField = mostPopularComment.find('.commenting-field'); expect(replyField.length).toBe(1); replyField.find('.close').click(); replyField = mostPopularComment.find('.commenting-field'); expect(replyField.length).toBe(0); }); it('Should be able to re-reply', function() { var childComment = mostPopularComment.find('.child-comments li.comment[data-id=9]'); childComment.find('.reply').first().click(); var replyField = mostPopularComment.find('.commenting-field'); expect(replyField.find('.reply-to-badge').val()).toBe('@Bryan Connery'); // Check that the field is last child var lastChild = mostPopularComment.find('.child-comments').children().last(); expect(lastChild[0]).toBe(replyField[0]); var replyText = 'This is a re-reply\nwith a new line'; replyField.find('.textarea').append(replyText).trigger('input'); var commentCount = comments.getComments().length; wait(function() { return comments.getComments().length == commentCount + 1; }); replyField.find('.send').trigger('click'); run(function() { // New reply should always be placed last var commentEl = mostPopularComment.find('li.comment').last(); var idOfNewComment = commentEl.data().id; expect(commentEl.find('.name .reply-to').text().indexOf('Bryan Connery')).not.toBe(-1); expect(commentEl.find('.content').text()).toBe(replyText); expect(commentEl.hasClass('by-current-user')).toBe(true); checkCommentElementData(commentEl); var toggleAllText = mostPopularComment.find('li.toggle-all').text(); expect(toggleAllText).toBe('View all 6 replies'); expect(mostPopularComment.find('li.comment:visible').length).toBe(2); }); }); it('Should be able to re-reply to a hidden reply', function() { mostPopularComment.find('.toggle-all').click(); var childComment = mostPopularComment.find('.child-comments li.comment').first(); childComment.find('.reply').first().click(); var replyField = mostPopularComment.find('.commenting-field'); expect(replyField.find('.reply-to-badge').val()).toBe('@Jack Hemsworth'); var replyText = 'This is a re-reply\nwith a new line'; replyField.find('.textarea').append(replyText).trigger('input'); var commentCount = comments.getComments().length; wait(function() { return comments.getComments().length == commentCount + 1; }); replyField.find('.send').trigger('click'); run(function() { // New reply should always be placed last var commentEl = mostPopularComment.find('li.comment').last(); var idOfNewComment = commentEl.data().id; expect(commentEl.find('.name .reply-to').text().indexOf('Jack Hemsworth')).not.toBe(-1); expect(commentEl.find('.content').text()).toBe(replyText); expect(commentEl.hasClass('by-current-user')).toBe(true); checkCommentElementData(commentEl); var toggleAllText = mostPopularComment.find('li.toggle-all').text(); expect(toggleAllText).toBe('Hide replies'); expect(mostPopularComment.find('li.comment:visible').length).toBe(6); }); }); it('Should reply to original user when erasing the reply-to badge', function() { var childComment = mostPopularComment.find('.child-comments li.comment').last(); childComment.find('.reply').first().click(); var replyField = mostPopularComment.find('.commenting-field'); var textarea = replyField.find('.textarea'); expect(parseInt(textarea.attr('data-parent'))).toBe(childComment.data().model.id); textarea.empty().trigger('input'); expect(parseInt(textarea.attr('data-parent'))).toBe(1); var replyText = 'This is a re-reply to original user'; replyField.find('.textarea').append(replyText).trigger('input'); var commentCount = comments.getComments().length; wait(function() { return comments.getComments().length == commentCount + 1; }); replyField.find('.send').trigger('click'); run(function() { var commentEl = mostPopularComment.find('li.comment').last(); expect(commentEl.find('.name .reply-to').length).toBe(0); }); }); }); describe('Editing', function() { var ownComment; var editButton; beforeEach(function() { ownComment = $('li.comment[data-id=3]'); editButton = ownComment.find('.edit'); }); it('Should show the edit button only for own comments', function() { expect(editButton.length).toBe(1); expect($('.edit').length).toBe(3); }); it('Should be able to open and close the edit field', function() { var cloneOfOwnComment = ownComment.clone(); editButton.click(); expect(ownComment.hasClass('edit')).toBe(true); // Check that the edit field exists var editField = ownComment.find('.commenting-field'); var textarea = editField.find('.textarea'); expect(editField.is(':visible')).toBe(true); // Check that other content is hidden ownComment.find('> .comment-wrapper > *:not(.commenting-field)').each(function(index, el) { expect($(el).is(':visible')).toBe(false); }); // Check the content var contentFromModel = ownComment.data().model.content; var contentFromUI = comments.getTextareaContent(textarea); expect(contentFromModel).toBe(contentFromUI); // Closing the field editField.find('.close').click(); expect(ownComment.hasClass('edit')).toBe(false); expect(editField.is(':visible')).toBe(false); // Check that other content is visible ownComment.find('> .comment-wrapper > *:not(.commenting-field)').each(function(index, el) { expect($(el).is(':visible')).toBe(true); }); // Check that the comment has not changed expect(ownComment[0].outerHTML).toBe(cloneOfOwnComment[0].outerHTML); }); it('Should be able to edit a main level comment', function() { testEditingComment(ownComment.data().model.id); }); it('Should be able to edit a reply', function() { ownComment.find('.reply').last().click(); var replyText = 'This is a re-reply'; var replyField = ownComment.find('.commenting-field'); replyField.find('.textarea').append(replyText).trigger('input'); // Create reply var commentCount = comments.getComments().length; wait(function() { return comments.getComments().length == commentCount + 1; }); replyField.find('.send').trigger('click'); // Test editing the reply run(function() { var reply = ownComment.find('.child-comments').children().last(); var replyId = reply.data().model.id; testEditingComment(replyId); }); // Test changing the parent of the reply run(function() { var reply = ownComment.find('.child-comments').children().last(); var replyId = reply.data().model.id; reply.find('.edit').click(); replyField = reply.find('.commenting-field'); var textarea = replyField.find('.textarea'); var saveButton = replyField.find('.save'); // Save button should be disabled textarea.trigger('input'); expect(saveButton.hasClass('enabled')).toBe(false); // Save button should be enabled textarea.find('.reply-to-badge').remove(); textarea.trigger('input'); expect(saveButton.hasClass('enabled')).toBe(true); var replyModelBefore = $.extend({},comments.commentsById[replyId]); expect(replyModelBefore.parent).toBe('5'); wait(function() { return comments.commentsById[replyId].parent != '5'; }); // Save the model saveButton.click(); run(function() { expect(comments.commentsById[replyId].parent).toBe('3'); }); }); }); it('Should not let the user save the comment if it hasn\'t changed', function() { editButton.click(); var editField = ownComment.find('.commenting-field'); var saveButton = editField.find('.save'); expect(saveButton.is(':visible')).toBe(true); expect(saveButton.hasClass('enabled')).toBe(false); var textarea = editField.find('.textarea'); var originalHTML = textarea.html(); // Append space textarea.append(' ').trigger('input'); expect(saveButton.hasClass('enabled')).toBe(true); // Revert changes textarea.html(originalHTML).trigger('input'); expect(saveButton.hasClass('enabled')).toBe(false); }); }); describe('Deleting', function() { it('Should show the delete button for own comments', function() { var ownComment = $('li.comment[data-id=3]'); var editButton = ownComment.find('.edit'); editButton.click(); var deleteButton = ownComment.find('.delete'); expect(deleteButton.length).toBe(1); expect(deleteButton.hasClass('enabled')).toBe(true); }); it('Should be able to delete a main level comment', function() { var commentId = 3; var ownComment = $('li.comment[data-id="'+commentId+'"]'); var childComments = comments.commentsById[commentId].childs.slice(); expect(childComments.length).toBe(2); var commentCountBeforeDelete = comments.getComments().length; var editButton = ownComment.find('.edit'); editButton.click(); wait(function() { return comments.getComments().length < commentCountBeforeDelete; }); var deleteButton = ownComment.find('.delete'); deleteButton.click(); run(function() { expect(comments.getComments().length).toBe(commentCountBeforeDelete - 3); // Expect childs to be deleted $(childComments).each(function(index, id) { expect(comments.commentsById[id]).toBe(undefined); expect($('li.comment[data-id="'+id+'"]').length).toBe(0); }); // Except the main comment to be deleted expect(comments.commentsById[commentId]).toBe(undefined); expect($('li.comment[data-id="'+commentId+'"]').length).toBe(0); }); }); it('Should be able to delete a reply', function() { var commentId = 10; var ownComment = $('li.comment[data-id="'+commentId+'"]'); var commentCountBeforeDelete = comments.getComments().length; var outermostParent = ownComment.parents('li.comment').last(); var toggleAllButton = outermostParent.find('.toggle-all'); // Check the child count expect(toggleAllButton.text()).toBe('View all 5 replies'); expect(comments.commentsById[outermostParent.attr('data-id')].childs.length).toBe(5); var editButton = ownComment.find('.edit'); editButton.click(); wait(function() { return comments.getComments().length < commentCountBeforeDelete; }); var deleteButton = ownComment.find('.delete'); deleteButton.click(); run(function() { expect(comments.getComments().length).toBe(commentCountBeforeDelete - 1); // Except the main comment to be deleted expect(comments.commentsById[commentId]).toBe(undefined); expect($('li.comment[data-id="'+commentId+'"]').length).toBe(0); // Check the child count expect(toggleAllButton.text()).toBe('View all 4 replies'); expect(comments.commentsById[outermostParent.attr('data-id')].childs.length).toBe(4); }); }); it('Should be able to delete a reply that has re-replies', function() { var commentId = 8; var reReplies = [9, 10]; var ownComment = $('li.comment[data-id="'+commentId+'"]'); var commentCountBeforeDelete = comments.getComments().length; var outermostParent = ownComment.parents('li.comment').last(); var toggleAllButton = outermostParent.find('.toggle-all'); // Check the child count expect(toggleAllButton.text()).toBe('View all 5 replies'); expect(comments.commentsById[outermostParent.attr('data-id')].childs.length).toBe(5); var editButton = ownComment.find('.edit'); editButton.click(); wait(function() { return comments.getComments().length < commentCountBeforeDelete; }); var deleteButton = ownComment.find('.delete'); deleteButton.click(); run(function() { expect(comments.getComments().length).toBe(commentCountBeforeDelete - 3); // Expect re-replies to be deleted $(reReplies).each(function(index, id) { expect(comments.commentsById[id]).toBe(undefined); expect($('li.comment[data-id="'+id+'"]').length).toBe(0); }); // Except the main comment to be deleted expect(comments.commentsById[commentId]).toBe(undefined); expect($('li.comment[data-id="'+commentId+'"]').length).toBe(0); // Check the child count expect(outermostParent.find('.toggle-all').length).toBe(0); expect(comments.commentsById[outermostParent.attr('data-id')].childs.length).toBe(2); }); }); }); describe('Upvoting', function() { it('Should be able to upvote a comment', function() { var commentId = 1; var commentEl = $('li.comment[data-id="'+commentId+'"]'); var commentModel = comments.commentsById[commentId]; // Check the status before upvoting var upvoteEl = commentEl.find('.upvote').first(); expect(commentModel.userHasUpvoted).toBe(false); expect(upvoteEl.hasClass('highlight-font')).toBe(false); expect(commentModel.upvoteCount).toBe(3); expect(upvoteEl.find('.upvote-count').text()).toBe('3'); upvoteEl.click(); // Check status after upvoting upvoteEl = commentEl.find('.upvote').first(); expect(commentModel.userHasUpvoted).toBe(true); expect(upvoteEl.hasClass('highlight-font')).toBe(true); expect(commentModel.upvoteCount).toBe(4); expect(upvoteEl.find('.upvote-count').text()).toBe('4'); }); it('Should be able to revoke an upvote', function() { var commentId = 3; var commentEl = $('li.comment[data-id="'+commentId+'"]'); var commentModel = comments.commentsById[commentId]; // Check the status before upvoting var upvoteEl = commentEl.find('.upvote').first(); expect(commentModel.userHasUpvoted).toBe(true); expect(upvoteEl.hasClass('highlight-font')).toBe(true); expect(commentModel.upvoteCount).toBe(2); expect(upvoteEl.find('.upvote-count').text()).toBe('2'); upvoteEl.click(); // Check status after upvoting upvoteEl = commentEl.find('.upvote').first(); expect(commentModel.userHasUpvoted).toBe(false); expect(upvoteEl.hasClass('highlight-font')).toBe(false); expect(commentModel.upvoteCount).toBe(1); expect(upvoteEl.find('.upvote-count').text()).toBe('1'); }); }); afterEach(function() { $('.jquery-comments').remove(); }); // Helpers // ======= function wait(callback) { $('.jquery-comments').hide(); waitsFor(callback); } function run(callback) { runs(function() { $('.jquery-comments').show(); callback(); }); } function checkCommentElementData(commentEl) { var nameContainer = commentEl.find('.name').first(); // Fields to be tested var profilePicture = commentEl.find('img.profile-picture').first().attr('src'); var replyTo = nameContainer.find('.reply-to').text(); var fullname = replyTo.length ? nameContainer.text().split(replyTo)[0] : nameContainer.text(); // Get content without edited timestamp var content = commentEl.find('.content').first().clone().children().remove().end().text(); var dateUI = new Date(commentEl.find('time').first().attr('data-original')); // Model that we are testing against var commentModel = commentEl.data().model; // Check basic fields expect(profilePicture).toBe(commentModel.profilePictureURL); expect(fullname).toBe(commentModel.fullname); expect(content).toBe(commentModel.content); // Check time var modelCreatedDate = new Date(commentModel.created); compareDates(dateUI, modelCreatedDate); } function compareDates(dateA, dateB) { expect(dateA.getDate()).toBe(dateB.getDate()); expect(dateA.getMonth()).toBe(dateB.getMonth()); expect(dateA.getFullYear()).toBe(dateB.getFullYear()); } function getOrder(elements) { return elements.map(function(index, commentEl){return $(commentEl).data().id}).toArray(); } function checkOrder(elements, expectedOrder) { var order = getOrder(elements); expect(JSON.stringify(order)).toBe(JSON.stringify(expectedOrder)); } function testEditingComment(id) { var ownComment = $('li.comment[data-id='+id+']'); var editButton = ownComment.find('.edit').first(); var ownCommentBefore = ownComment.clone(); var ownCommentModelBefore = $.extend({},comments.commentsById[id]); editButton.click(); var editField = ownComment.find('.commenting-field'); var textarea = editField.find('.textarea'); // Edit the comment var modifiedContent = '<br>appended content with new line'; textarea.append(modifiedContent).trigger('input'); // Save the comment var originalContent = comments.commentsById[id].content; wait(function() { return comments.commentsById[id].content != originalContent; }); editField.find('.save').click(); run(function() { expect(editField.is(':visible')).toBe(false); // Check the edited comment ownComment = $('li.comment[data-id='+id+']'); checkCommentElementData(ownComment); expect(ownComment.find('.content .edited').text().length).not.toBe(0); // Check that only fields content and modified have changed in comment model var ownCommentModel = comments.commentsById[id]; $(Object.keys(ownCommentModel)).each(function(index, key) { if(key == 'content' || key == 'modified') { expect(ownCommentModel[key]).not.toBe(ownCommentModelBefore[key]); } else { expect(ownCommentModel[key]).toBe(ownCommentModelBefore[key]); } }); // Check that only content has changed in comment element ownComment = ownComment.clone(); ownComment.find('.content').remove(); ownCommentBefore.find('.content').remove(); expect(ownComment[0].outerHTML).toBe(ownCommentBefore[0].outerHTML); }); } });