Signed-off-by: Robin Appelman <robin@icewind.nl>tags/v15.0.0beta1
@@ -1,56 +0,0 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2016, ownCloud, Inc. | |||
* | |||
* @author Bart Visscher <bartv@thisnet.nl> | |||
* @author Björn Schießle <bjoern@schiessle.org> | |||
* @author Frank Karlitschek <frank@karlitschek.de> | |||
* @author Lukas Reschke <lukas@statuscode.ch> | |||
* @author Sam Tuke <mail@samtuke.com> | |||
* @author Vincent Petry <pvince81@owncloud.com> | |||
* | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* This program 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, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
\OC_JSON::checkLoggedIn(); | |||
\OC_JSON::callCheck(); | |||
\OC_JSON::checkAppEnabled('files_versions'); | |||
$source = (string)$_GET['source']; | |||
$start = (int)$_GET['start']; | |||
list ($uid, $filename) = OCA\Files_Versions\Storage::getUidAndFilename($source); | |||
$count = 5; //show the newest revisions | |||
$versions = OCA\Files_Versions\Storage::getVersions($uid, $filename, $source); | |||
if( $versions ) { | |||
$endReached = false; | |||
if (count($versions) <= $start+$count) { | |||
$endReached = true; | |||
} | |||
$versions = array_slice($versions, $start, $count); | |||
// remove owner path from request to not disclose it to the recipient | |||
foreach ($versions as $version) { | |||
unset($version['path']); | |||
} | |||
\OC_JSON::success(array('data' => array('versions' => $versions, 'endReached' => $endReached))); | |||
} else { | |||
\OC_JSON::success(array('data' => array('versions' => [], 'endReached' => true))); | |||
} |
@@ -1,41 +0,0 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2016, ownCloud, Inc. | |||
* | |||
* @author Bart Visscher <bartv@thisnet.nl> | |||
* @author Björn Schießle <bjoern@schiessle.org> | |||
* @author Frank Karlitschek <frank@karlitschek.de> | |||
* @author Lukas Reschke <lukas@statuscode.ch> | |||
* @author Robin Appelman <robin@icewind.nl> | |||
* @author Sam Tuke <mail@samtuke.com> | |||
* @author Thomas Müller <thomas.mueller@tmit.eu> | |||
* @author Thomas Tanghus <thomas@tanghus.net> | |||
* | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* This program 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, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
\OC_JSON::checkLoggedIn(); | |||
\OC_JSON::checkAppEnabled('files_versions'); | |||
\OC_JSON::callCheck(); | |||
$file = (string)$_GET['file']; | |||
$revision=(int)$_GET['revision']; | |||
if(OCA\Files_Versions\Storage::rollback( $file, $revision )) { | |||
\OC_JSON::success(array("data" => array( "revision" => $revision, "file" => $file ))); | |||
}else{ | |||
$l = \OC::$server->getL10N('files_versions'); | |||
\OC_JSON::error(array("data" => array( "message" => $l->t("Could not revert: %s", array($file) )))); | |||
} |
@@ -1,59 +0,0 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2016, ownCloud, Inc. | |||
* | |||
* @author Andreas Fischer <bantu@owncloud.com> | |||
* @author Björn Schießle <bjoern@schiessle.org> | |||
* @author Lukas Reschke <lukas@statuscode.ch> | |||
* @author Morris Jobke <hey@morrisjobke.de> | |||
* @author Roeland Jago Douma <roeland@famdouma.nl> | |||
* @author Vincent Petry <pvince81@owncloud.com> | |||
* | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* This program 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, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
\OC_JSON::checkAppEnabled('files_versions'); | |||
\OC_JSON::checkLoggedIn(); | |||
$file = $_GET['file']; | |||
$revision=(int)$_GET['revision']; | |||
try { | |||
list($uid, $filename) = OCA\Files_Versions\Storage::getUidAndFilename($file); | |||
} catch(\OCP\Files\NotFoundException $e) { | |||
http_response_code(404); | |||
$tmpl = new OCP\Template('', '404', 'guest'); | |||
$tmpl->assign('file', ''); | |||
$tmpl->printPage(); | |||
exit(); | |||
} | |||
$versionName = '/'.$uid.'/files_versions/'.$filename.'.v'.$revision; | |||
$view = new OC\Files\View('/'); | |||
$ftype = \OC::$server->getMimeTypeDetector()->getSecureMimeType($view->getMimeType('/'.$uid.'/files/'.$filename)); | |||
header('Content-Type:'.$ftype); | |||
\OC_Response::setContentDispositionHeader(basename($filename), 'attachment'); | |||
header('Pragma: public');// enable caching in IE | |||
header('Expires: 0'); | |||
header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); | |||
\OC_Response::setContentLengthHeader($view->filesize($versionName)); | |||
OC_Util::obEnd(); | |||
$view->readfile($versionName); |
@@ -24,7 +24,9 @@ templates['item'] = template({"1":function(container,depth0,helpers,partials,dat | |||
+ alias4(((helper = (helper = helpers.previewUrl || (depth0 != null ? depth0.previewUrl : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"previewUrl","hash":{},"data":data}) : helper))) | |||
+ "\" width=\"44\" height=\"44\"/>\n </div>\n <div class=\"version-container\">\n <div>\n <a href=\"" | |||
+ alias4(((helper = (helper = helpers.downloadUrl || (depth0 != null ? depth0.downloadUrl : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"downloadUrl","hash":{},"data":data}) : helper))) | |||
+ "\" class=\"downloadVersion\"><img src=\"" | |||
+ "\" class=\"downloadVersion\" download=\"" | |||
+ alias4(((helper = (helper = helpers.downloadName || (depth0 != null ? depth0.downloadName : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"downloadName","hash":{},"data":data}) : helper))) | |||
+ "\"><img src=\"" | |||
+ alias4(((helper = (helper = helpers.downloadIconUrl || (depth0 != null ? depth0.downloadIconUrl : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"downloadIconUrl","hash":{},"data":data}) : helper))) | |||
+ "\" />\n <span class=\"versiondate has-tooltip live-relative-timestamp\" data-timestamp=\"" | |||
+ alias4(((helper = (helper = helpers.millisecondsTimestamp || (depth0 != null ? depth0.millisecondsTimestamp : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"millisecondsTimestamp","hash":{},"data":data}) : helper))) |
@@ -5,7 +5,7 @@ | |||
</div> | |||
<div class="version-container"> | |||
<div> | |||
<a href="{{downloadUrl}}" class="downloadVersion"><img src="{{downloadIconUrl}}" /> | |||
<a href="{{downloadUrl}}" class="downloadVersion" download="{{downloadName}}"><img src="{{downloadIconUrl}}" /> | |||
<span class="versiondate has-tooltip live-relative-timestamp" data-timestamp="{{millisecondsTimestamp}}" title="{{formattedTimestamp}}">{{relativeTimestamp}}</span> | |||
</a> | |||
</div> |
@@ -8,86 +8,72 @@ | |||
* | |||
*/ | |||
(function() { | |||
(function () { | |||
/** | |||
* @memberof OCA.Versions | |||
*/ | |||
var VersionCollection = OC.Backbone.Collection.extend({ | |||
model: OCA.Versions.VersionModel, | |||
sync: OC.Backbone.davSync, | |||
/** | |||
* @var OCA.Files.FileInfoModel | |||
*/ | |||
_fileInfo: null, | |||
_endReached: false, | |||
_currentIndex: 0, | |||
_currentUser: null, | |||
url: function() { | |||
var url = OC.generateUrl('/apps/files_versions/ajax/getVersions.php'); | |||
var query = { | |||
source: this._fileInfo.getFullPath(), | |||
start: this._currentIndex | |||
}; | |||
return url + '?' + OC.buildQueryString(query); | |||
}, | |||
_client: null, | |||
setFileInfo: function(fileInfo) { | |||
setFileInfo: function (fileInfo) { | |||
this._fileInfo = fileInfo; | |||
// reset | |||
this._endReached = false; | |||
this._currentIndex = 0; | |||
}, | |||
getFileInfo: function() { | |||
getFileInfo: function () { | |||
return this._fileInfo; | |||
}, | |||
hasMoreResults: function() { | |||
return !this._endReached; | |||
setCurrentUser: function(user) { | |||
this._currentUser = user; | |||
}, | |||
fetch: function(options) { | |||
if (!options || options.remove) { | |||
this._currentIndex = 0; | |||
} | |||
return OC.Backbone.Collection.prototype.fetch.apply(this, arguments); | |||
getCurrentUser: function() { | |||
return this._currentUser || OC.getCurrentUser().uid; | |||
}, | |||
/** | |||
* Fetch the next set of results | |||
*/ | |||
fetchNext: function() { | |||
if (!this.hasMoreResults()) { | |||
return null; | |||
} | |||
if (this._currentIndex === 0) { | |||
return this.fetch(); | |||
} | |||
return this.fetch({remove: false}); | |||
setClient: function(client) { | |||
this._client = client; | |||
}, | |||
getClient: function() { | |||
return this._client || new OC.Files.Client({ | |||
host: OC.getHost(), | |||
root: OC.linkToRemoteBase('dav') + '/versions/' + this.getCurrentUser(), | |||
useHTTPS: OC.getProtocol() === 'https' | |||
}); | |||
}, | |||
reset: function() { | |||
this._currentIndex = 0; | |||
OC.Backbone.Collection.prototype.reset.apply(this, arguments); | |||
url: function () { | |||
return OC.linkToRemoteBase('dav') + '/versions/' + this.getCurrentUser() + '/versions/' + this._fileInfo.get('id'); | |||
}, | |||
parse: function(result) { | |||
var fullPath = this._fileInfo.getFullPath(); | |||
var results = _.map(result.data.versions, function(version) { | |||
var revision = parseInt(version.version, 10); | |||
return { | |||
id: revision, | |||
name: version.name, | |||
fullPath: fullPath, | |||
timestamp: revision, | |||
size: version.size, | |||
mimetype: version.mimetype | |||
}; | |||
var fileId = this._fileInfo.get('id'); | |||
var name = this._fileInfo.get('name'); | |||
var user = this.getCurrentUser(); | |||
var client = this.getClient(); | |||
return _.map(result, function(version) { | |||
version.fullPath = fullPath; | |||
version.fileId = fileId; | |||
version.name = name; | |||
version.timestamp = parseInt(moment(new Date(version.timestamp)).format('X'), 10); | |||
version.id = parseInt(OC.basename(version.href), 10); | |||
version.size = parseInt(version.size, 10); | |||
version.user = user; | |||
version.client = client; | |||
return version; | |||
}); | |||
this._endReached = result.data.endReached; | |||
this._currentIndex += results.length; | |||
return results; | |||
} | |||
}); | |||
@@ -8,50 +8,50 @@ | |||
* | |||
*/ | |||
(function() { | |||
/* global moment */ | |||
(function () { | |||
/** | |||
* @memberof OCA.Versions | |||
*/ | |||
var VersionModel = OC.Backbone.Model.extend({ | |||
sync: OC.Backbone.davSync, | |||
davProperties: { | |||
'size': '{DAV:}getcontentlength', | |||
'mimetype': '{DAV:}getcontenttype', | |||
'timestamp': '{DAV:}getlastmodified', | |||
}, | |||
/** | |||
* Restores the original file to this revision | |||
*/ | |||
revert: function(options) { | |||
revert: function (options) { | |||
options = options ? _.clone(options) : {}; | |||
var model = this; | |||
var file = this.getFullPath(); | |||
var revision = this.get('timestamp'); | |||
$.ajax({ | |||
type: 'GET', | |||
url: OC.generateUrl('/apps/files_versions/ajax/rollbackVersion.php'), | |||
dataType: 'json', | |||
data: { | |||
file: file, | |||
revision: revision | |||
}, | |||
success: function(response) { | |||
if (response.status === 'error') { | |||
if (options.error) { | |||
options.error.call(options.context, model, response, options); | |||
} | |||
model.trigger('error', model, response, options); | |||
} else { | |||
if (options.success) { | |||
options.success.call(options.context, model, response, options); | |||
} | |||
model.trigger('revert', model, response, options); | |||
var client = this.get('client'); | |||
return client.move('/versions/' + this.get('fileId') + '/' + this.get('id'), '/restore/target', true) | |||
.done(function () { | |||
if (options.success) { | |||
options.success.call(options.context, model, {}, options); | |||
} | |||
model.trigger('revert', model, options); | |||
}) | |||
.fail(function () { | |||
if (options.error) { | |||
options.error.call(options.context, model, {}, options); | |||
} | |||
} | |||
}); | |||
model.trigger('error', model, {}, options); | |||
}); | |||
}, | |||
getFullPath: function() { | |||
getFullPath: function () { | |||
return this.get('fullPath'); | |||
}, | |||
getPreviewUrl: function() { | |||
getPreviewUrl: function () { | |||
var url = OC.generateUrl('/apps/files_versions/preview'); | |||
var params = { | |||
file: this.get('fullPath'), | |||
@@ -60,13 +60,8 @@ | |||
return url + '?' + OC.buildQueryString(params); | |||
}, | |||
getDownloadUrl: function() { | |||
var url = OC.generateUrl('/apps/files_versions/download.php'); | |||
var params = { | |||
file: this.get('fullPath'), | |||
revision: this.get('timestamp') | |||
}; | |||
return url + '?' + OC.buildQueryString(params); | |||
getDownloadUrl: function () { | |||
return OC.linkToRemoteBase('dav') + '/versions/' + this.get('user') + '/versions/' + this.get('fileId') + '/' + this.get('id'); | |||
} | |||
}); | |||
@@ -8,14 +8,11 @@ | |||
* | |||
*/ | |||
/* @global Handlebars */ | |||
(function() { | |||
/** | |||
* @memberof OCA.Versions | |||
*/ | |||
var VersionsTabView = OCA.Files.DetailTabView.extend( | |||
/** @lends OCA.Versions.VersionsTabView.prototype */ { | |||
var VersionsTabView = OCA.Files.DetailTabView.extend(/** @lends OCA.Versions.VersionsTabView.prototype */{ | |||
id: 'versionsTabView', | |||
className: 'tab versionsTabView', | |||
@@ -24,8 +21,7 @@ | |||
$versionsContainer: null, | |||
events: { | |||
'click .revertVersion': '_onClickRevertVersion', | |||
'click .showMoreVersions': '_onClickShowMoreVersions' | |||
'click .revertVersion': '_onClickRevertVersion' | |||
}, | |||
initialize: function() { | |||
@@ -43,19 +39,14 @@ | |||
}, | |||
nextPage: function() { | |||
if (this._loading || !this.collection.hasMoreResults()) { | |||
if (this._loading) { | |||
return; | |||
} | |||
if (this.collection.getFileInfo() && this.collection.getFileInfo().isDirectory()) { | |||
return; | |||
} | |||
this.collection.fetchNext(); | |||
}, | |||
_onClickShowMoreVersions: function(ev) { | |||
ev.preventDefault(); | |||
this.nextPage(); | |||
this.collection.fetch(); | |||
}, | |||
_onClickRevertVersion: function(ev) { | |||
@@ -70,8 +61,6 @@ | |||
ev.preventDefault(); | |||
revision = $target.attr('data-revision'); | |||
this.$el.find('.versions, .showMoreVersions').addClass('hidden'); | |||
var versionModel = this.collection.get(revision); | |||
versionModel.revert({ | |||
success: function() { | |||
@@ -79,7 +68,7 @@ | |||
self.$versionsContainer.empty(); | |||
self.collection.setFileInfo(fileInfoModel); | |||
self.collection.reset([], {silent: true}); | |||
self.collection.fetchNext(); | |||
self.collection.fetch(); | |||
self.$el.find('.versions').removeClass('hidden'); | |||
@@ -97,7 +86,7 @@ | |||
fileInfoModel.trigger('busy', fileInfoModel, false); | |||
self.$el.find('.versions').removeClass('hidden'); | |||
self._toggleLoading(false); | |||
OC.Notification.show(t('files_version', 'Failed to revert {file} to revision {timestamp}.', | |||
OC.Notification.show(t('files_version', 'Failed to revert {file} to revision {timestamp}.', | |||
{ | |||
file: versionModel.getFullPath(), | |||
timestamp: OC.Util.formatDate(versionModel.get('timestamp') * 1000) | |||
@@ -121,27 +110,16 @@ | |||
_onRequest: function() { | |||
this._toggleLoading(true); | |||
this.$el.find('.showMoreVersions').addClass('hidden'); | |||
}, | |||
_onEndRequest: function() { | |||
this._toggleLoading(false); | |||
this.$el.find('.empty').toggleClass('hidden', !!this.collection.length); | |||
this.$el.find('.showMoreVersions').toggleClass('hidden', !this.collection.hasMoreResults()); | |||
}, | |||
_onAddModel: function(model) { | |||
var $el = $(this.itemTemplate(this._formatItem(model))); | |||
this.$versionsContainer.append($el); | |||
var preview = $el.find('.preview')[0]; | |||
this._lazyLoadPreview({ | |||
url: model.getPreviewUrl(), | |||
mime: model.get('mimetype'), | |||
callback: function(url) { | |||
preview.src = url; | |||
} | |||
}); | |||
$el.find('.has-tooltip').tooltip(); | |||
}, | |||
@@ -168,8 +146,9 @@ | |||
_formatItem: function(version) { | |||
var timestamp = version.get('timestamp') * 1000; | |||
var size = version.has('size') ? version.get('size') : 0; | |||
return _.extend({ | |||
millisecondsTimestamp: timestamp, | |||
versionId: version.get('id'), | |||
formattedTimestamp: OC.Util.formatDate(timestamp), | |||
relativeTimestamp: OC.Util.relativeModifiedDate(timestamp), | |||
humanReadableSize: OC.Util.humanFileSize(size, true), | |||
@@ -177,7 +156,9 @@ | |||
hasDetails: version.has('size'), | |||
downloadUrl: version.getDownloadUrl(), | |||
downloadIconUrl: OC.imagePath('core', 'actions/download'), | |||
downloadName: version.get('name'), | |||
revertIconUrl: OC.imagePath('core', 'actions/history'), | |||
previewUrl: version.getPreviewUrl(), | |||
revertLabel: t('files_versions', 'Restore'), | |||
canRevert: (this.collection.getFileInfo().get('permissions') & OC.PERMISSION_UPDATE) !== 0 | |||
}, version.attributes); | |||
@@ -188,8 +169,7 @@ | |||
*/ | |||
render: function() { | |||
this.$el.html(this.template({ | |||
emptyResultLabel: t('files_versions', 'No earlier versions available'), | |||
moreVersionsLabel: t('files_versions', 'More versions …') | |||
emptyResultLabel: t('files_versions', 'No other versions available'), | |||
})); | |||
this.$el.find('.has-tooltip').tooltip(); | |||
this.$versionsContainer = this.$el.find('ul.versions'); | |||
@@ -206,38 +186,6 @@ | |||
return false; | |||
} | |||
return !fileInfo.isDirectory(); | |||
}, | |||
/** | |||
* Lazy load a file's preview. | |||
* | |||
* @param path path of the file | |||
* @param mime mime type | |||
* @param callback callback function to call when the image was loaded | |||
* @param etag file etag (for caching) | |||
*/ | |||
_lazyLoadPreview : function(options) { | |||
var url = options.url; | |||
var mime = options.mime; | |||
var ready = options.callback; | |||
// get mime icon url | |||
var iconURL = OC.MimeType.getIconUrl(mime); | |||
ready(iconURL); // set mimeicon URL | |||
var img = new Image(); | |||
img.onload = function(){ | |||
// if loading the preview image failed (no preview for the mimetype) then img.width will < 5 | |||
if (img.width > 5) { | |||
ready(url, img); | |||
} else if (options.error) { | |||
options.error(); | |||
} | |||
}; | |||
if (options.error) { | |||
img.onerror = options.error; | |||
} | |||
img.src = url; | |||
} | |||
}); | |||
@@ -14,148 +14,21 @@ describe('OCA.Versions.VersionCollection', function() { | |||
beforeEach(function() { | |||
fileInfoModel = new OCA.Files.FileInfoModel({ | |||
path: '/subdir', | |||
name: 'some file.txt' | |||
name: 'some file.txt', | |||
id: 10, | |||
}); | |||
collection = new VersionCollection(); | |||
collection.setFileInfo(fileInfoModel); | |||
collection.setCurrentUser('user'); | |||
}); | |||
it('fetches the next page', function() { | |||
collection.fetchNext(); | |||
it('fetches the versions', function() { | |||
collection.fetch(); | |||
expect(fakeServer.requests.length).toEqual(1); | |||
expect(fakeServer.requests[0].url).toEqual( | |||
OC.generateUrl('apps/files_versions/ajax/getVersions.php') + | |||
'?source=%2Fsubdir%2Fsome%20file.txt&start=0' | |||
OC.linkToRemoteBase('dav') + '/versions/user/versions/10' | |||
); | |||
fakeServer.requests[0].respond( | |||
200, | |||
{ 'Content-Type': 'application/json' }, | |||
JSON.stringify({ | |||
status: 'success', | |||
data: { | |||
endReached: false, | |||
versions: [{ | |||
version: 10000000, | |||
size: 123, | |||
name: 'some file.txt', | |||
fullPath: '/subdir/some file.txt' | |||
},{ | |||
version: 15000000, | |||
size: 150, | |||
name: 'some file.txt', | |||
path: '/subdir/some file.txt' | |||
}] | |||
} | |||
}) | |||
); | |||
expect(collection.length).toEqual(2); | |||
expect(collection.hasMoreResults()).toEqual(true); | |||
collection.fetchNext(); | |||
expect(fakeServer.requests.length).toEqual(2); | |||
expect(fakeServer.requests[1].url).toEqual( | |||
OC.generateUrl('apps/files_versions/ajax/getVersions.php') + | |||
'?source=%2Fsubdir%2Fsome%20file.txt&start=2' | |||
); | |||
fakeServer.requests[1].respond( | |||
200, | |||
{ 'Content-Type': 'application/json' }, | |||
JSON.stringify({ | |||
status: 'success', | |||
data: { | |||
endReached: true, | |||
versions: [{ | |||
version: 18000000, | |||
size: 123, | |||
name: 'some file.txt', | |||
path: '/subdir/some file.txt' | |||
}] | |||
} | |||
}) | |||
); | |||
expect(collection.length).toEqual(3); | |||
expect(collection.hasMoreResults()).toEqual(false); | |||
collection.fetchNext(); | |||
// no further requests | |||
expect(fakeServer.requests.length).toEqual(2); | |||
}); | |||
it('properly parses the results', function() { | |||
collection.fetchNext(); | |||
expect(fakeServer.requests.length).toEqual(1); | |||
expect(fakeServer.requests[0].url).toEqual( | |||
OC.generateUrl('apps/files_versions/ajax/getVersions.php') + | |||
'?source=%2Fsubdir%2Fsome%20file.txt&start=0' | |||
); | |||
fakeServer.requests[0].respond( | |||
200, | |||
{ 'Content-Type': 'application/json' }, | |||
JSON.stringify({ | |||
status: 'success', | |||
data: { | |||
endReached: false, | |||
versions: [{ | |||
version: 10000000, | |||
size: 123, | |||
name: 'some file.txt', | |||
path: '/subdir/some file.txt' | |||
},{ | |||
version: 15000000, | |||
size: 150, | |||
name: 'some file.txt', | |||
path: '/subdir/some file.txt' | |||
}] | |||
} | |||
}) | |||
); | |||
expect(collection.length).toEqual(2); | |||
var model = collection.at(0); | |||
expect(model.get('id')).toEqual(10000000); | |||
expect(model.get('timestamp')).toEqual(10000000); | |||
expect(model.get('name')).toEqual('some file.txt'); | |||
expect(model.get('fullPath')).toEqual('/subdir/some file.txt'); | |||
expect(model.get('size')).toEqual(123); | |||
model = collection.at(1); | |||
expect(model.get('id')).toEqual(15000000); | |||
expect(model.get('timestamp')).toEqual(15000000); | |||
expect(model.get('name')).toEqual('some file.txt'); | |||
expect(model.get('fullPath')).toEqual('/subdir/some file.txt'); | |||
expect(model.get('size')).toEqual(150); | |||
}); | |||
it('resets page counted when setting a new file info model', function() { | |||
collection.fetchNext(); | |||
expect(fakeServer.requests.length).toEqual(1); | |||
fakeServer.requests[0].respond( | |||
200, | |||
{ 'Content-Type': 'application/json' }, | |||
JSON.stringify({ | |||
status: 'success', | |||
data: { | |||
endReached: true, | |||
versions: [{ | |||
version: 18000000, | |||
size: 123, | |||
name: 'some file.txt', | |||
path: '/subdir/some file.txt' | |||
}] | |||
} | |||
}) | |||
); | |||
expect(collection.hasMoreResults()).toEqual(false); | |||
collection.setFileInfo(fileInfoModel); | |||
expect(collection.hasMoreResults()).toEqual(true); | |||
fakeServer.requests[0].respond(200); | |||
}); | |||
}); | |||
@@ -10,14 +10,23 @@ | |||
describe('OCA.Versions.VersionModel', function() { | |||
var VersionModel = OCA.Versions.VersionModel; | |||
var model; | |||
var uid = OC.currentUser = 'user'; | |||
beforeEach(function() { | |||
model = new VersionModel({ | |||
id: 10000000, | |||
fileId: 10, | |||
timestamp: 10000000, | |||
fullPath: '/subdir/some file.txt', | |||
name: 'some file.txt', | |||
size: 150 | |||
size: 150, | |||
user: 'user', | |||
client: new OC.Files.Client({ | |||
host: 'localhost', | |||
port: 80, | |||
root: '/remote.php/dav/versions/user', | |||
useHTTPS: OC.getProtocol() === 'https' | |||
}) | |||
}); | |||
}); | |||
@@ -32,8 +41,8 @@ describe('OCA.Versions.VersionModel', function() { | |||
}); | |||
it('returns the download url', function() { | |||
expect(model.getDownloadUrl()) | |||
.toEqual(OC.generateUrl('/apps/files_versions/download.php') + | |||
'?file=%2Fsubdir%2Fsome%20file.txt&revision=10000000' | |||
.toEqual(OC.linkToRemoteBase('dav') + '/versions/' + uid + | |||
'/versions/10/10000000' | |||
); | |||
}); | |||
describe('reverting', function() { | |||
@@ -50,46 +59,40 @@ describe('OCA.Versions.VersionModel', function() { | |||
model.on('error', errorStub); | |||
}); | |||
it('tells the server to revert when calling the revert method', function() { | |||
model.revert({ | |||
var promise = model.revert({ | |||
success: successStub | |||
}); | |||
expect(fakeServer.requests.length).toEqual(1); | |||
expect(fakeServer.requests[0].url) | |||
var request = fakeServer.requests[0]; | |||
expect(request.url) | |||
.toEqual( | |||
OC.generateUrl('/apps/files_versions/ajax/rollbackVersion.php') + | |||
'?file=%2Fsubdir%2Fsome+file.txt&revision=10000000' | |||
OC.linkToRemoteBase('dav') + '/versions/user/versions/10/10000000' | |||
); | |||
expect(request.requestHeaders.Destination).toEqual(OC.getRootPath() + '/remote.php/dav/versions/user/restore/target'); | |||
request.respond(201); | |||
fakeServer.requests[0].respond( | |||
200, | |||
{ 'Content-Type': 'application/json' }, | |||
JSON.stringify({ | |||
status: 'success', | |||
}) | |||
); | |||
promise.then(function() { | |||
expect(revertEventStub.calledOnce).toEqual(true); | |||
expect(successStub.calledOnce).toEqual(true); | |||
expect(errorStub.notCalled).toEqual(true); | |||
}); | |||
expect(revertEventStub.calledOnce).toEqual(true); | |||
expect(successStub.calledOnce).toEqual(true); | |||
expect(errorStub.notCalled).toEqual(true); | |||
return promise; | |||
}); | |||
it('triggers error event when server returns a failure', function() { | |||
model.revert({ | |||
var promise = model.revert({ | |||
success: successStub | |||
}); | |||
expect(fakeServer.requests.length).toEqual(1); | |||
fakeServer.requests[0].respond( | |||
200, | |||
{ 'Content-Type': 'application/json' }, | |||
JSON.stringify({ | |||
status: 'error', | |||
}) | |||
); | |||
fakeServer.requests[0].respond(404); | |||
expect(revertEventStub.notCalled).toEqual(true); | |||
expect(successStub.notCalled).toEqual(true); | |||
expect(errorStub.calledOnce).toEqual(true); | |||
promise.then(function() { | |||
expect(revertEventStub.notCalled).toEqual(true); | |||
expect(successStub.notCalled).toEqual(true); | |||
expect(errorStub.calledOnce).toEqual(true); | |||
}); | |||
}); | |||
}); | |||
}); |
@@ -82,14 +82,12 @@ describe('OCA.Versions.VersionsTabView', function() { | |||
expect($item.find('.versiondate').text()).toEqual('seconds ago'); | |||
expect($item.find('.size').text()).toEqual('< 1 KB'); | |||
expect($item.find('.revertVersion').length).toEqual(1); | |||
expect($item.find('.preview').attr('src')).toEqual('http://localhost/core/img/filetypes/text.svg'); | |||
$item = $versions.eq(1); | |||
expect($item.find('.downloadVersion').attr('href')).toEqual(version2.getDownloadUrl()); | |||
expect($item.find('.versiondate').text()).toEqual('2 days ago'); | |||
expect($item.find('.size').text()).toEqual('< 1 KB'); | |||
expect($item.find('.revertVersion').length).toEqual(1); | |||
expect($item.find('.preview').attr('src')).toEqual('http://localhost/core/img/filetypes/text.svg'); | |||
}); | |||
it('does not render revert button when no update permissions', function() { | |||
@@ -106,71 +104,11 @@ describe('OCA.Versions.VersionsTabView', function() { | |||
expect($item.find('.downloadVersion').attr('href')).toEqual(version1.getDownloadUrl()); | |||
expect($item.find('.versiondate').text()).toEqual('seconds ago'); | |||
expect($item.find('.revertVersion').length).toEqual(0); | |||
expect($item.find('.preview').attr('src')).toEqual('http://localhost/core/img/filetypes/text.svg'); | |||
$item = $versions.eq(1); | |||
expect($item.find('.downloadVersion').attr('href')).toEqual(version2.getDownloadUrl()); | |||
expect($item.find('.versiondate').text()).toEqual('2 days ago'); | |||
expect($item.find('.revertVersion').length).toEqual(0); | |||
expect($item.find('.preview').attr('src')).toEqual('http://localhost/core/img/filetypes/text.svg'); | |||
}); | |||
}); | |||
describe('More versions', function() { | |||
var hasMoreResultsStub; | |||
beforeEach(function() { | |||
tabView.setFileInfo(fileInfoModel); | |||
fetchStub.reset(); | |||
tabView.collection.set(testVersions); | |||
hasMoreResultsStub = sinon.stub(VersionCollection.prototype, 'hasMoreResults'); | |||
}); | |||
afterEach(function() { | |||
hasMoreResultsStub.restore(); | |||
}); | |||
it('shows "More versions" button when more versions are available', function() { | |||
hasMoreResultsStub.returns(true); | |||
tabView.collection.trigger('sync'); | |||
expect(tabView.$el.find('.showMoreVersions').hasClass('hidden')).toEqual(false); | |||
}); | |||
it('does not show "More versions" button when more versions are available', function() { | |||
hasMoreResultsStub.returns(false); | |||
tabView.collection.trigger('sync'); | |||
expect(tabView.$el.find('.showMoreVersions').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); | |||
tabView.$el.find('.showMoreVersions').click(); | |||
expect(fetchStub.calledOnce).toEqual(true); | |||
}); | |||
it('appends version to the list when added to collection', function() { | |||
var time3 = Date.UTC(2015, 6, 10, 1, 0, 0, 0) / 1000; | |||
var version3 = new VersionModel({ | |||
id: time3, | |||
timestamp: time3, | |||
name: 'some file.txt', | |||
size: 54, | |||
fullPath: '/subdir/some file.txt', | |||
mimetype: 'text/plain' | |||
}); | |||
tabView.collection.add(version3); | |||
expect(tabView.$el.find('.versions>li').length).toEqual(3); | |||
var $item = tabView.$el.find('.versions>li').eq(2); | |||
expect($item.find('.downloadVersion').attr('href')).toEqual(version3.getDownloadUrl()); | |||
expect($item.find('.versiondate').text()).toEqual('7 days ago'); | |||
expect($item.find('.revertVersion').length).toEqual(1); | |||
expect($item.find('.preview').attr('src')).toEqual('http://localhost/core/img/filetypes/text.svg'); | |||
}); | |||
}); | |||