fileactionsmenuSpec.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. /**
  2. * ownCloud
  3. *
  4. * @author Vincent Petry
  5. * @copyright 2015 Vincent Petry <pvince81@owncloud.com>
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
  9. * License as published by the Free Software Foundation; either
  10. * version 3 of the License, or any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
  16. *
  17. * You should have received a copy of the GNU Affero General Public
  18. * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  19. *
  20. */
  21. describe('OCA.Files.FileActionsMenu tests', function() {
  22. var fileList, fileActions, menu, actionStub, menuContext, $tr;
  23. beforeEach(function() {
  24. // init horrible parameters
  25. var $body = $('#testArea');
  26. $body.append('<input type="hidden" id="dir" value="/subdir"></input>');
  27. $body.append('<input type="hidden" id="permissions" value="31"></input>');
  28. // dummy files table
  29. actionStub = sinon.stub();
  30. fileActions = new OCA.Files.FileActions();
  31. fileList = new OCA.Files.FileList($body, {
  32. fileActions: fileActions
  33. });
  34. fileActions.registerAction({
  35. name: 'Testdropdown',
  36. displayName: 'Testdropdowndisplay',
  37. mime: 'all',
  38. permissions: OC.PERMISSION_READ,
  39. icon: function () {
  40. return OC.imagePath('core', 'actions/download');
  41. },
  42. actionHandler: actionStub
  43. });
  44. fileActions.registerAction({
  45. name: 'Testdropdownnoicon',
  46. displayName: 'Testdropdowndisplaynoicon',
  47. mime: 'all',
  48. permissions: OC.PERMISSION_READ,
  49. actionHandler: actionStub
  50. });
  51. fileActions.registerAction({
  52. name: 'Testinline',
  53. displayName: 'Testinlinedisplay',
  54. type: OCA.Files.FileActions.TYPE_INLINE,
  55. mime: 'all',
  56. permissions: OC.PERMISSION_READ
  57. });
  58. fileActions.registerAction({
  59. name: 'Testdefault',
  60. displayName: 'Testdefaultdisplay',
  61. mime: 'all',
  62. permissions: OC.PERMISSION_READ
  63. });
  64. fileActions.setDefault('all', 'Testdefault');
  65. var fileData = {
  66. id: 18,
  67. type: 'file',
  68. name: 'testName.txt',
  69. mimetype: 'text/plain',
  70. size: '1234',
  71. etag: 'a01234c',
  72. mtime: '123456'
  73. };
  74. $tr = fileList.add(fileData);
  75. menuContext = {
  76. $file: $tr,
  77. fileList: fileList,
  78. fileActions: fileActions,
  79. dir: fileList.getCurrentDirectory()
  80. };
  81. menu = new OCA.Files.FileActionsMenu();
  82. menu.show(menuContext);
  83. });
  84. afterEach(function() {
  85. fileActions = null;
  86. fileList.destroy();
  87. fileList = undefined;
  88. menu.remove();
  89. $('#dir, #permissions, #filestable').remove();
  90. });
  91. describe('rendering', function() {
  92. it('renders dropdown actions in menu', function() {
  93. var $action = menu.$el.find('a[data-action=Testdropdown]');
  94. expect($action.length).toEqual(1);
  95. expect($action.find('img').attr('src'))
  96. .toEqual(OC.imagePath('core', 'actions/download'));
  97. expect($action.find('.no-icon').length).toEqual(0);
  98. $action = menu.$el.find('a[data-action=Testdropdownnoicon]');
  99. expect($action.length).toEqual(1);
  100. expect($action.find('img').length).toEqual(0);
  101. expect($action.find('.no-icon').length).toEqual(1);
  102. });
  103. it('does not render default actions', function() {
  104. expect(menu.$el.find('a[data-action=Testdefault]').length).toEqual(0);
  105. });
  106. it('does not render inline actions', function() {
  107. expect(menu.$el.find('a[data-action=Testinline]').length).toEqual(0);
  108. });
  109. it('only renders actions relevant to the mime type', function() {
  110. fileActions.registerAction({
  111. name: 'Match',
  112. displayName: 'MatchDisplay',
  113. mime: 'text/plain',
  114. permissions: OC.PERMISSION_READ
  115. });
  116. fileActions.registerAction({
  117. name: 'Nomatch',
  118. displayName: 'NoMatchDisplay',
  119. mime: 'application/octet-stream',
  120. permissions: OC.PERMISSION_READ
  121. });
  122. menu.render();
  123. expect(menu.$el.find('a[data-action=Match]').length).toEqual(1);
  124. expect(menu.$el.find('a[data-action=NoMatch]').length).toEqual(0);
  125. });
  126. it('only renders actions relevant to the permissions', function() {
  127. fileActions.registerAction({
  128. name: 'Match',
  129. displayName: 'MatchDisplay',
  130. mime: 'text/plain',
  131. permissions: OC.PERMISSION_UPDATE
  132. });
  133. fileActions.registerAction({
  134. name: 'Nomatch',
  135. displayName: 'NoMatchDisplay',
  136. mime: 'text/plain',
  137. permissions: OC.PERMISSION_DELETE
  138. });
  139. menu.render();
  140. expect(menu.$el.find('a[data-action=Match]').length).toEqual(1);
  141. expect(menu.$el.find('a[data-action=NoMatch]').length).toEqual(0);
  142. });
  143. it('sorts by order attribute, then name', function() {
  144. fileActions.registerAction({
  145. name: 'Baction',
  146. displayName: 'Baction',
  147. order: 2,
  148. mime: 'text/plain',
  149. permissions: OC.PERMISSION_ALL
  150. });
  151. fileActions.registerAction({
  152. name: 'Zaction',
  153. displayName: 'Zaction',
  154. order: 1,
  155. mime: 'text/plain',
  156. permissions: OC.PERMISSION_ALL
  157. });
  158. fileActions.registerAction({
  159. name: 'Yaction',
  160. displayName: 'Yaction',
  161. mime: 'text/plain',
  162. permissions: OC.PERMISSION_ALL
  163. });
  164. fileActions.registerAction({
  165. name: 'Waction',
  166. displayName: 'Waction',
  167. mime: 'text/plain',
  168. permissions: OC.PERMISSION_ALL
  169. });
  170. menu.render();
  171. var zactionIndex = menu.$el.find('a[data-action=Zaction]').closest('li').index();
  172. var bactionIndex = menu.$el.find('a[data-action=Baction]').closest('li').index();
  173. expect(zactionIndex).toBeLessThan(bactionIndex);
  174. var wactionIndex = menu.$el.find('a[data-action=Waction]').closest('li').index();
  175. var yactionIndex = menu.$el.find('a[data-action=Yaction]').closest('li').index();
  176. expect(wactionIndex).toBeLessThan(yactionIndex);
  177. });
  178. it('calls displayName function', function() {
  179. var displayNameStub = sinon.stub().returns('Test');
  180. fileActions.registerAction({
  181. name: 'Something',
  182. displayName: displayNameStub,
  183. mime: 'text/plain',
  184. permissions: OC.PERMISSION_ALL
  185. });
  186. menu.render();
  187. expect(displayNameStub.calledOnce).toEqual(true);
  188. expect(displayNameStub.calledWith(menuContext)).toEqual(true);
  189. expect(menu.$el.find('a[data-action=Something] span:not(.icon)').text()).toEqual('Test');
  190. });
  191. it('uses plain iconClass', function() {
  192. fileActions.registerAction({
  193. name: 'Something',
  194. mime: 'text/plain',
  195. permissions: OC.PERMISSION_ALL,
  196. iconClass: 'test'
  197. });
  198. menu.render();
  199. expect(menu.$el.find('a[data-action=Something]').children('span.icon').hasClass('test')).toEqual(true);
  200. });
  201. it('calls iconClass function', function() {
  202. var iconClassStub = sinon.stub().returns('test');
  203. fileActions.registerAction({
  204. name: 'Something',
  205. mime: 'text/plain',
  206. permissions: OC.PERMISSION_ALL,
  207. iconClass: iconClassStub
  208. });
  209. menu.render();
  210. expect(iconClassStub.calledOnce).toEqual(true);
  211. expect(iconClassStub.calledWith(menuContext.$file.attr('data-file'), menuContext)).toEqual(true);
  212. expect(menu.$el.find('a[data-action=Something]').children('span.icon').hasClass('test')).toEqual(true);
  213. });
  214. });
  215. describe('action handler', function() {
  216. it('calls action handler when clicking menu item', function() {
  217. var $action = menu.$el.find('a[data-action=Testdropdown]');
  218. $action.click();
  219. expect(actionStub.calledOnce).toEqual(true);
  220. expect(actionStub.getCall(0).args[0]).toEqual('testName.txt');
  221. expect(actionStub.getCall(0).args[1].$file[0]).toEqual($tr[0]);
  222. expect(actionStub.getCall(0).args[1].fileList).toEqual(fileList);
  223. expect(actionStub.getCall(0).args[1].fileActions).toEqual(fileActions);
  224. expect(actionStub.getCall(0).args[1].dir).toEqual('/subdir');
  225. });
  226. });
  227. describe('default actions from registerDefaultActions', function() {
  228. beforeEach(function() {
  229. fileActions.clear();
  230. fileActions.registerDefaultActions();
  231. });
  232. it('redirects to download URL when clicking download', function() {
  233. var redirectStub = sinon.stub(OC, 'redirect');
  234. var fileData = {
  235. id: 18,
  236. type: 'file',
  237. name: 'testName.txt',
  238. mimetype: 'text/plain',
  239. size: '1234',
  240. etag: 'a01234c',
  241. mtime: '123456'
  242. };
  243. var $tr = fileList.add(fileData);
  244. fileActions.display($tr.find('td.filename'), true, fileList);
  245. var menuContext = {
  246. $file: $tr,
  247. fileList: fileList,
  248. fileActions: fileActions,
  249. fileInfoModel: new OCA.Files.FileInfoModel(fileData),
  250. dir: fileList.getCurrentDirectory()
  251. };
  252. menu = new OCA.Files.FileActionsMenu();
  253. menu.show(menuContext);
  254. menu.$el.find('.action-download').click();
  255. expect(redirectStub.calledOnce).toEqual(true);
  256. expect(redirectStub.getCall(0).args[0]).toContain(
  257. OC.getRootPath() +
  258. '/remote.php/webdav/subdir/testName.txt'
  259. );
  260. redirectStub.restore();
  261. });
  262. it('takes the file\'s path into account when clicking download', function() {
  263. var redirectStub = sinon.stub(OC, 'redirect');
  264. var fileData = {
  265. id: 18,
  266. type: 'file',
  267. name: 'testName.txt',
  268. path: '/anotherpath/there',
  269. mimetype: 'text/plain',
  270. size: '1234',
  271. etag: 'a01234c',
  272. mtime: '123456'
  273. };
  274. var $tr = fileList.add(fileData);
  275. fileActions.display($tr.find('td.filename'), true, fileList);
  276. var menuContext = {
  277. $file: $tr,
  278. fileList: fileList,
  279. fileActions: fileActions,
  280. fileInfoModel: new OCA.Files.FileInfoModel(fileData),
  281. dir: '/anotherpath/there'
  282. };
  283. menu = new OCA.Files.FileActionsMenu();
  284. menu.show(menuContext);
  285. menu.$el.find('.action-download').click();
  286. expect(redirectStub.calledOnce).toEqual(true);
  287. expect(redirectStub.getCall(0).args[0]).toContain(
  288. OC.getRootPath() + '/remote.php/webdav/anotherpath/there/testName.txt'
  289. );
  290. redirectStub.restore();
  291. });
  292. it('deletes file when clicking delete', function() {
  293. var deleteStub = sinon.stub(fileList, 'do_delete');
  294. var fileData = {
  295. id: 18,
  296. type: 'file',
  297. name: 'testName.txt',
  298. path: '/somepath/dir',
  299. mimetype: 'text/plain',
  300. size: '1234',
  301. etag: 'a01234c',
  302. mtime: '123456'
  303. };
  304. var $tr = fileList.add(fileData);
  305. fileActions.display($tr.find('td.filename'), true, fileList);
  306. var menuContext = {
  307. $file: $tr,
  308. fileList: fileList,
  309. fileActions: fileActions,
  310. fileInfoModel: new OCA.Files.FileInfoModel(fileData),
  311. dir: '/somepath/dir'
  312. };
  313. menu = new OCA.Files.FileActionsMenu();
  314. menu.show(menuContext);
  315. menu.$el.find('.action-delete').click();
  316. expect(deleteStub.calledOnce).toEqual(true);
  317. expect(deleteStub.getCall(0).args[0]).toEqual('testName.txt');
  318. expect(deleteStub.getCall(0).args[1]).toEqual('/somepath/dir');
  319. deleteStub.restore();
  320. });
  321. });
  322. });