appSpec.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. /**
  2. * ownCloud
  3. *
  4. * @author Vincent Petry
  5. * @copyright 2014 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.App tests', function() {
  22. var App = OCA.Files.App;
  23. var pushStateStub;
  24. var parseUrlQueryStub;
  25. var oldLegacyFileActions;
  26. beforeEach(function() {
  27. $('#testArea').append(
  28. '<div id="content" class="app-files">' +
  29. '<div id="app-navigation">' +
  30. '<ul><li data-id="files"><a>Files</a></li>' +
  31. '<li data-id="other"><a>Other</a></li>' +
  32. '</div>' +
  33. '<div id="app-content">' +
  34. '<div id="app-content-files" class="hidden">' +
  35. '</div>' +
  36. '<div id="app-content-other" class="hidden">' +
  37. '</div>' +
  38. '</div>' +
  39. '</div>' +
  40. '</div>'
  41. );
  42. oldLegacyFileActions = window.FileActions;
  43. window.FileActions = new OCA.Files.FileActions();
  44. OCA.Files.legacyFileActions = window.FileActions;
  45. OCA.Files.fileActions = new OCA.Files.FileActions();
  46. pushStateStub = sinon.stub(OC.Util.History, 'pushState');
  47. parseUrlQueryStub = sinon.stub(OC.Util.History, 'parseUrlQuery');
  48. parseUrlQueryStub.returns({});
  49. App.initialize();
  50. });
  51. afterEach(function() {
  52. App.destroy();
  53. window.FileActions = oldLegacyFileActions;
  54. pushStateStub.restore();
  55. parseUrlQueryStub.restore();
  56. });
  57. describe('initialization', function() {
  58. it('initializes the default file list with the default file actions', function() {
  59. expect(App.fileList).toBeDefined();
  60. expect(App.fileList.fileActions.actions.all).toBeDefined();
  61. expect(App.fileList.$el.is('#app-content-files')).toEqual(true);
  62. });
  63. it('merges the legacy file actions with the default ones', function() {
  64. var legacyActionStub = sinon.stub();
  65. var actionStub = sinon.stub();
  66. // legacy action
  67. window.FileActions.register(
  68. 'all',
  69. 'LegacyTest',
  70. OC.PERMISSION_READ,
  71. OC.imagePath('core', 'actions/test'),
  72. legacyActionStub
  73. );
  74. // legacy action to be overwritten
  75. window.FileActions.register(
  76. 'all',
  77. 'OverwriteThis',
  78. OC.PERMISSION_READ,
  79. OC.imagePath('core', 'actions/test'),
  80. legacyActionStub
  81. );
  82. // regular file actions
  83. OCA.Files.fileActions.register(
  84. 'all',
  85. 'RegularTest',
  86. OC.PERMISSION_READ,
  87. OC.imagePath('core', 'actions/test'),
  88. actionStub
  89. );
  90. // overwrite
  91. OCA.Files.fileActions.register(
  92. 'all',
  93. 'OverwriteThis',
  94. OC.PERMISSION_READ,
  95. OC.imagePath('core', 'actions/test'),
  96. actionStub
  97. );
  98. App.initialize();
  99. var actions = App.fileList.fileActions.actions;
  100. expect(actions.all.OverwriteThis.action).toBe(actionStub);
  101. expect(actions.all.LegacyTest.action).toBe(legacyActionStub);
  102. expect(actions.all.RegularTest.action).toBe(actionStub);
  103. // default one still there
  104. expect(actions.dir.Open.action).toBeDefined();
  105. });
  106. });
  107. describe('URL handling', function() {
  108. it('pushes the state to the URL when current app changed directory', function() {
  109. $('#app-content-files').trigger(new $.Event('changeDirectory', {dir: 'subdir'}));
  110. expect(pushStateStub.calledOnce).toEqual(true);
  111. expect(pushStateStub.getCall(0).args[0].dir).toEqual('subdir');
  112. expect(pushStateStub.getCall(0).args[0].view).not.toBeDefined();
  113. $('li[data-id=other]>a').click();
  114. pushStateStub.reset();
  115. $('#app-content-other').trigger(new $.Event('changeDirectory', {dir: 'subdir'}));
  116. expect(pushStateStub.calledOnce).toEqual(true);
  117. expect(pushStateStub.getCall(0).args[0].dir).toEqual('subdir');
  118. expect(pushStateStub.getCall(0).args[0].view).toEqual('other');
  119. });
  120. describe('onpopstate', function() {
  121. it('sends "urlChanged" event to current app', function() {
  122. var handler = sinon.stub();
  123. $('#app-content-files').on('urlChanged', handler);
  124. App._onPopState({view: 'files', dir: '/somedir'});
  125. expect(handler.calledOnce).toEqual(true);
  126. expect(handler.getCall(0).args[0].view).toEqual('files');
  127. expect(handler.getCall(0).args[0].dir).toEqual('/somedir');
  128. });
  129. it('sends "show" event to current app and sets navigation', function() {
  130. var showHandlerFiles = sinon.stub();
  131. var showHandlerOther = sinon.stub();
  132. var hideHandlerFiles = sinon.stub();
  133. var hideHandlerOther = sinon.stub();
  134. $('#app-content-files').on('show', showHandlerFiles);
  135. $('#app-content-files').on('hide', hideHandlerFiles);
  136. $('#app-content-other').on('show', showHandlerOther);
  137. $('#app-content-other').on('hide', hideHandlerOther);
  138. App._onPopState({view: 'other', dir: '/somedir'});
  139. expect(showHandlerFiles.notCalled).toEqual(true);
  140. expect(hideHandlerFiles.calledOnce).toEqual(true);
  141. expect(showHandlerOther.calledOnce).toEqual(true);
  142. expect(hideHandlerOther.notCalled).toEqual(true);
  143. showHandlerFiles.reset();
  144. showHandlerOther.reset();
  145. hideHandlerFiles.reset();
  146. hideHandlerOther.reset();
  147. App._onPopState({view: 'files', dir: '/somedir'});
  148. expect(showHandlerFiles.calledOnce).toEqual(true);
  149. expect(hideHandlerFiles.notCalled).toEqual(true);
  150. expect(showHandlerOther.notCalled).toEqual(true);
  151. expect(hideHandlerOther.calledOnce).toEqual(true);
  152. expect(App.navigation.getActiveItem()).toEqual('files');
  153. expect($('#app-content-files').hasClass('hidden')).toEqual(false);
  154. expect($('#app-content-other').hasClass('hidden')).toEqual(true);
  155. });
  156. it('does not send "show" or "hide" event to current app when already visible', function() {
  157. var showHandler = sinon.stub();
  158. var hideHandler = sinon.stub();
  159. $('#app-content-files').on('show', showHandler);
  160. $('#app-content-files').on('hide', hideHandler);
  161. App._onPopState({view: 'files', dir: '/somedir'});
  162. expect(showHandler.notCalled).toEqual(true);
  163. expect(hideHandler.notCalled).toEqual(true);
  164. });
  165. it('state defaults to files app with root dir', function() {
  166. var handler = sinon.stub();
  167. parseUrlQueryStub.returns({});
  168. $('#app-content-files').on('urlChanged', handler);
  169. App._onPopState();
  170. expect(handler.calledOnce).toEqual(true);
  171. expect(handler.getCall(0).args[0].view).toEqual('files');
  172. expect(handler.getCall(0).args[0].dir).toEqual('/');
  173. });
  174. it('activates files app if invalid view is passed', function() {
  175. App._onPopState({view: 'invalid', dir: '/somedir'});
  176. expect(App.navigation.getActiveItem()).toEqual('files');
  177. expect($('#app-content-files').hasClass('hidden')).toEqual(false);
  178. });
  179. });
  180. describe('navigation', function() {
  181. it('switches the navigation item and panel visibility when onpopstate', function() {
  182. App._onPopState({view: 'other', dir: '/somedir'});
  183. expect(App.navigation.getActiveItem()).toEqual('other');
  184. expect($('#app-content-files').hasClass('hidden')).toEqual(true);
  185. expect($('#app-content-other').hasClass('hidden')).toEqual(false);
  186. expect($('li[data-id=files]').hasClass('active')).toEqual(false);
  187. expect($('li[data-id=other]').hasClass('active')).toEqual(true);
  188. App._onPopState({view: 'files', dir: '/somedir'});
  189. expect(App.navigation.getActiveItem()).toEqual('files');
  190. expect($('#app-content-files').hasClass('hidden')).toEqual(false);
  191. expect($('#app-content-other').hasClass('hidden')).toEqual(true);
  192. expect($('li[data-id=files]').hasClass('active')).toEqual(true);
  193. expect($('li[data-id=other]').hasClass('active')).toEqual(false);
  194. });
  195. it('clicking on navigation switches the panel visibility', function() {
  196. $('li[data-id=other]>a').click();
  197. expect(App.navigation.getActiveItem()).toEqual('other');
  198. expect($('#app-content-files').hasClass('hidden')).toEqual(true);
  199. expect($('#app-content-other').hasClass('hidden')).toEqual(false);
  200. expect($('li[data-id=files]').hasClass('active')).toEqual(false);
  201. expect($('li[data-id=other]').hasClass('active')).toEqual(true);
  202. $('li[data-id=files]>a').click();
  203. expect(App.navigation.getActiveItem()).toEqual('files');
  204. expect($('#app-content-files').hasClass('hidden')).toEqual(false);
  205. expect($('#app-content-other').hasClass('hidden')).toEqual(true);
  206. expect($('li[data-id=files]').hasClass('active')).toEqual(true);
  207. expect($('li[data-id=other]').hasClass('active')).toEqual(false);
  208. });
  209. it('clicking on navigation sends "show" and "urlChanged" event', function() {
  210. var handler = sinon.stub();
  211. var showHandler = sinon.stub();
  212. $('#app-content-other').on('urlChanged', handler);
  213. $('#app-content-other').on('show', showHandler);
  214. $('li[data-id=other]>a').click();
  215. expect(handler.calledOnce).toEqual(true);
  216. expect(handler.getCall(0).args[0].view).toEqual('other');
  217. expect(handler.getCall(0).args[0].dir).toEqual('/');
  218. expect(showHandler.calledOnce).toEqual(true);
  219. });
  220. it('clicking on activate navigation only sends "urlChanged" event', function() {
  221. var handler = sinon.stub();
  222. var showHandler = sinon.stub();
  223. $('#app-content-files').on('urlChanged', handler);
  224. $('#app-content-files').on('show', showHandler);
  225. $('li[data-id=files]>a').click();
  226. expect(handler.calledOnce).toEqual(true);
  227. expect(handler.getCall(0).args[0].view).toEqual('files');
  228. expect(handler.getCall(0).args[0].dir).toEqual('/');
  229. expect(showHandler.notCalled).toEqual(true);
  230. });
  231. });
  232. describe('viewer mode', function() {
  233. it('toggles the sidebar when viewer mode is enabled', function() {
  234. $('#app-content-files').trigger(
  235. new $.Event('changeViewerMode', {viewerModeEnabled: true}
  236. ));
  237. expect($('#app-navigation').hasClass('hidden')).toEqual(true);
  238. expect($('.app-files').hasClass('viewer-mode no-sidebar')).toEqual(true);
  239. $('#app-content-files').trigger(
  240. new $.Event('changeViewerMode', {viewerModeEnabled: false}
  241. ));
  242. expect($('#app-navigation').hasClass('hidden')).toEqual(false);
  243. expect($('.app-files').hasClass('viewer-mode no-sidebar')).toEqual(false);
  244. });
  245. });
  246. });
  247. });