Added JS unit tests for comments

This commit is contained in:
Vincent Petry 2016-02-02 15:13:45 +01:00
parent 9028457ea2
commit 03f4b49ecc
5 changed files with 320 additions and 6 deletions

View File

@ -13,14 +13,14 @@
var NS_OWNCLOUD = 'http://owncloud.org/ns';
/**
* @class OCA.Comments.CommentsCollection
* @class OCA.Comments.CommentCollection
* @classdesc
*
* Collection of comments assigned to a file
*
*/
var CommentsCollection = OC.Backbone.Collection.extend(
/** @lends OCA.Comments.CommentsCollection.prototype */ {
var CommentCollection = OC.Backbone.Collection.extend(
/** @lends OCA.Comments.CommentCollection.prototype */ {
sync: OC.Backbone.davSync,
@ -82,7 +82,7 @@
options = _.extend({
remove: false,
data: body,
davProperties: CommentsCollection.prototype.model.prototype.davProperties,
davProperties: CommentCollection.prototype.model.prototype.davProperties,
success: function(resp) {
if (resp.length <= self._limit) {
// no new entries, end reached
@ -105,6 +105,6 @@
}
});
OCA.Comments.CommentsCollection = CommentsCollection;
OCA.Comments.CommentCollection = CommentCollection;
})(OC, OCA);

View File

@ -57,7 +57,7 @@
initialize: function() {
OCA.Files.DetailTabView.prototype.initialize.apply(this, arguments);
this.collection = new OCA.Comments.CommentsCollection();
this.collection = new OCA.Comments.CommentCollection();
this.collection.on('request', this._onRequest, this);
this.collection.on('sync', this._onEndRequest, this);
this.collection.on('add', this._onAddModel, this);

View File

@ -0,0 +1,104 @@
/*
* Copyright (c) 2016
*
* This file is licensed under the Affero General Public License comment 3
* or later.
*
* See the COPYING-README file.
*
*/
describe('OCA.Comments.CommentCollection', function() {
var CommentCollection = OCA.Comments.CommentCollection;
var collection, syncStub;
var comment1, comment2, comment3;
beforeEach(function() {
syncStub = sinon.stub(CommentCollection.prototype, 'sync');
collection = new CommentCollection();
collection.setObjectId(5);
comment1 = {
id: 1,
actorType: 'users',
actorId: 'user1',
actorDisplayName: 'User One',
objectType: 'files',
objectId: 5,
message: 'First',
creationDateTime: Date.UTC(2016, 1, 3, 10, 5, 0)
};
comment2 = {
id: 2,
actorType: 'users',
actorId: 'user2',
actorDisplayName: 'User Two',
objectType: 'files',
objectId: 5,
message: 'Second\nNewline',
creationDateTime: Date.UTC(2016, 1, 3, 10, 0, 0)
};
comment3 = {
id: 3,
actorType: 'users',
actorId: 'user3',
actorDisplayName: 'User Three',
objectType: 'files',
objectId: 5,
message: 'Third',
creationDateTime: Date.UTC(2016, 1, 3, 5, 0, 0)
};
});
afterEach(function() {
syncStub.restore();
});
it('fetches the next page', function() {
collection._limit = 2;
collection.fetchNext();
expect(syncStub.calledOnce).toEqual(true);
expect(syncStub.lastCall.args[0]).toEqual('REPORT');
var options = syncStub.lastCall.args[2];
expect(options.remove).toEqual(false);
var parser = new DOMParser();
var doc = parser.parseFromString(options.data, "application/xml");
expect(doc.getElementsByTagNameNS('http://owncloud.org/ns', 'limit')[0].textContent).toEqual('3');
expect(doc.getElementsByTagNameNS('http://owncloud.org/ns', 'offset')[0].textContent).toEqual('0');
syncStub.yieldTo('success', [comment1, comment2, comment3]);
expect(collection.length).toEqual(2);
expect(collection.hasMoreResults()).toEqual(true);
collection.fetchNext();
expect(syncStub.calledTwice).toEqual(true);
options = syncStub.lastCall.args[2];
doc = parser.parseFromString(options.data, "application/xml");
expect(doc.getElementsByTagNameNS('http://owncloud.org/ns', 'limit')[0].textContent).toEqual('3');
expect(doc.getElementsByTagNameNS('http://owncloud.org/ns', 'offset')[0].textContent).toEqual('2');
syncStub.yieldTo('success', [comment3]);
expect(collection.length).toEqual(3);
expect(collection.hasMoreResults()).toEqual(false);
collection.fetchNext();
// no further requests
expect(syncStub.calledTwice).toEqual(true);
});
it('resets page counted when calling reset', function() {
collection.fetchNext();
syncStub.yieldTo('success', [comment1]);
expect(collection.hasMoreResults()).toEqual(false);
collection.reset();
expect(collection.hasMoreResults()).toEqual(true);
});
});

View File

@ -0,0 +1,198 @@
/**
* ownCloud
*
* @author Vincent Petry
* @copyright 2016 Vincent Petry <pvince81@owncloud.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* comment 3 of the License, or any later comment.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
describe('OCA.Comments.CommentsTabView tests', function() {
var view, fileInfoModel;
var fetchStub;
var testComments;
var clock;
beforeEach(function() {
clock = sinon.useFakeTimers(Date.UTC(2016, 1, 3, 10, 5, 9));
fetchStub = sinon.stub(OCA.Comments.CommentCollection.prototype, 'fetchNext');
view = new OCA.Comments.CommentsTabView();
fileInfoModel = new OCA.Files.FileInfoModel({
id: 5,
name: 'One.txt',
mimetype: 'text/plain',
permissions: 31,
path: '/subdir',
size: 123456789,
etag: 'abcdefg',
mtime: Date.UTC(2016, 1, 0, 0, 0, 0)
});
view.render();
var comment1 = new OCA.Comments.CommentModel({
id: 1,
actorType: 'users',
actorId: 'user1',
actorDisplayName: 'User One',
objectType: 'files',
objectId: 5,
message: 'First',
creationDateTime: Date.UTC(2016, 1, 3, 10, 5, 0)
});
var comment2 = new OCA.Comments.CommentModel({
id: 2,
actorType: 'users',
actorId: 'user2',
actorDisplayName: 'User Two',
objectType: 'files',
objectId: 5,
message: 'Second\nNewline',
creationDateTime: Date.UTC(2016, 1, 3, 10, 0, 0)
});
testComments = [comment1, comment2];
});
afterEach(function() {
view.remove();
view = undefined;
fetchStub.restore();
clock.restore();
});
describe('rendering', function() {
it('reloads matching comments when setting file info model', function() {
view.setFileInfo(fileInfoModel);
expect(fetchStub.calledOnce).toEqual(true);
});
it('renders loading icon while fetching comments', function() {
view.setFileInfo(fileInfoModel);
view.collection.trigger('request');
expect(view.$el.find('.loading').length).toEqual(1);
expect(view.$el.find('.comments li').length).toEqual(0);
});
it('renders comments', function() {
view.setFileInfo(fileInfoModel);
view.collection.set(testComments);
var $comments = view.$el.find('.comments>li');
expect($comments.length).toEqual(2);
var $item = $comments.eq(0);
expect($item.find('.author').text()).toEqual('User One');
expect($item.find('.date').text()).toEqual('seconds ago');
expect($item.find('.message').text()).toEqual('First');
$item = $comments.eq(1);
expect($item.find('.author').text()).toEqual('User Two');
expect($item.find('.date').text()).toEqual('5 minutes ago');
expect($item.find('.message').html()).toEqual('Second<br>Newline');
});
});
describe('more comments', function() {
var hasMoreResultsStub;
beforeEach(function() {
view.collection.set(testComments);
hasMoreResultsStub = sinon.stub(OCA.Comments.CommentCollection.prototype, 'hasMoreResults');
});
afterEach(function() {
hasMoreResultsStub.restore();
});
it('shows "More comments" button when more comments are available', function() {
hasMoreResultsStub.returns(true);
view.collection.trigger('sync');
expect(view.$el.find('.showMore').hasClass('hidden')).toEqual(false);
});
it('does not show "More comments" button when more comments are available', function() {
hasMoreResultsStub.returns(false);
view.collection.trigger('sync');
expect(view.$el.find('.showMore').hasClass('hidden')).toEqual(true);
});
it('fetches and appends the next page when clicking the "More" button', function() {
hasMoreResultsStub.returns(true);
expect(fetchStub.notCalled).toEqual(true);
view.$el.find('.showMore').click();
expect(fetchStub.calledOnce).toEqual(true);
});
it('appends comment to the list when added to collection', function() {
var comment3 = new OCA.Comments.CommentModel({
id: 3,
actorType: 'users',
actorId: 'user3',
actorDisplayName: 'User Three',
objectType: 'files',
objectId: 5,
message: 'Third',
creationDateTime: Date.UTC(2016, 1, 3, 5, 0, 0)
});
view.collection.add(comment3);
expect(view.$el.find('.comments>li').length).toEqual(3);
var $item = view.$el.find('.comments>li').eq(2);
expect($item.find('.author').text()).toEqual('User Three');
expect($item.find('.date').text()).toEqual('5 hours ago');
expect($item.find('.message').html()).toEqual('Third');
});
});
describe('posting comments', function() {
var createStub;
var currentUserStub;
beforeEach(function() {
view.collection.set(testComments);
createStub = sinon.stub(OCA.Comments.CommentCollection.prototype, 'create');
currentUserStub = sinon.stub(OC, 'getCurrentUser');
currentUserStub.returns({
uid: 'testuser',
displayName: 'Test User'
});
});
afterEach(function() {
createStub.restore();
currentUserStub.restore();
});
it('creates a new comment when clicking post button', function() {
view.$el.find('.message').val('New message');
view.$el.find('form').submit();
expect(createStub.calledOnce).toEqual(true);
expect(createStub.lastCall.args[0]).toEqual({
actorId: 'testuser',
actorDisplayName: 'Test User',
actorType: 'users',
verb: 'comment',
message: 'New message',
creationDateTime: Date.UTC(2016, 1, 3, 10, 5, 9)
});
});
it('does not create a comment if the field is empty', function() {
view.$el.find('.message').val(' ');
view.$el.find('form').submit();
expect(createStub.notCalled).toEqual(true);
});
});
});

View File

@ -82,6 +82,18 @@ module.exports = function(config) {
],
testFiles: ['apps/files_versions/tests/js/**/*.js']
},
{
name: 'comments',
srcFiles: [
// need to enforce loading order...
'apps/comments/js/app.js',
'apps/comments/js/commentmodel.js',
'apps/comments/js/commentcollection.js',
'apps/comments/js/commentstabview.js',
'apps/comments/js/filesplugin'
],
testFiles: ['apps/comments/tests/js/**/*.js']
},
{
name: 'systemtags',
srcFiles: [