appSpec.js 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /**
  2. * @copyright 2014 Vincent Petry <pvince81@owncloud.com>
  3. *
  4. * @author John Molakvoæ <skjnldsv@protonmail.com>
  5. * @author Vincent Petry <vincent@nextcloud.com>
  6. *
  7. * @license AGPL-3.0-or-later
  8. *
  9. * This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Affero General Public License as
  11. * published by the Free Software Foundation, either version 3 of the
  12. * License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Affero General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. *
  22. */
  23. describe('OCA.Files.App tests', function() {
  24. var App = OCA.Files.App;
  25. var pushStateStub;
  26. var replaceStateStub;
  27. var parseUrlQueryStub;
  28. beforeEach(function() {
  29. $('#testArea').append(
  30. '<div id="content" class="app-files">' +
  31. '<div id="app-navigation">' +
  32. '<ul><li data-id="files"><a>Files</a></li>' +
  33. '<li data-id="other"><a>Other</a></li>' +
  34. '</div>' +
  35. '<div id="app-content">' +
  36. '<div id="app-content-files" class="hidden">' +
  37. '</div>' +
  38. '<div id="app-content-other" class="hidden">' +
  39. '</div>' +
  40. '</div>' +
  41. '</div>' +
  42. '</div>'
  43. );
  44. OCA.Files.fileActions = new OCA.Files.FileActions();
  45. pushStateStub = sinon.stub(OC.Util.History, 'pushState');
  46. replaceStateStub = sinon.stub(OC.Util.History, 'replaceState');
  47. parseUrlQueryStub = sinon.stub(OC.Util.History, 'parseUrlQuery');
  48. parseUrlQueryStub.returns({});
  49. App.initialize();
  50. });
  51. afterEach(function() {
  52. App.destroy();
  53. pushStateStub.restore();
  54. replaceStateStub.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. });
  64. describe('URL handling', function() {
  65. it('pushes the state to the URL when current app changed directory', function() {
  66. $('#app-content-files').trigger(new $.Event('changeDirectory', {dir: 'sub dir'}));
  67. expect(pushStateStub.calledOnce).toEqual(true);
  68. var params = OC.parseQueryString(pushStateStub.getCall(0).args[0]);
  69. expect(params.dir).toEqual('sub dir');
  70. expect(params.view).not.toBeDefined();
  71. $('li[data-id=other]>a').click();
  72. pushStateStub.reset();
  73. $('#app-content-other').trigger(new $.Event('changeDirectory', {dir: 'sub dir'}));
  74. expect(pushStateStub.calledOnce).toEqual(true);
  75. params = OC.parseQueryString(pushStateStub.getCall(0).args[0]);
  76. expect(params.dir).toEqual('sub dir');
  77. expect(params.view).toEqual('other');
  78. });
  79. it('replaces the state to the URL when fileid is known', function() {
  80. $('#app-content-files').trigger(new $.Event('changeDirectory', {dir: 'sub dir'}));
  81. expect(pushStateStub.calledOnce).toEqual(true);
  82. var params = OC.parseQueryString(pushStateStub.getCall(0).args[0]);
  83. expect(params.dir).toEqual('sub dir');
  84. expect(params.view).not.toBeDefined();
  85. expect(replaceStateStub.notCalled).toEqual(true);
  86. parseUrlQueryStub.returns({dir: 'sub dir'});
  87. $('#app-content-files').trigger(new $.Event('afterChangeDirectory', {dir: 'sub dir', fileId: 123}));
  88. expect(pushStateStub.calledOnce).toEqual(true);
  89. expect(replaceStateStub.calledOnce).toEqual(true);
  90. params = OC.parseQueryString(replaceStateStub.getCall(0).args[0]);
  91. expect(params.dir).toEqual('sub dir');
  92. expect(params.view).not.toBeDefined();
  93. expect(params.fileid).toEqual('123');
  94. });
  95. describe('onpopstate', function() {
  96. it('sends "urlChanged" event to current app', function() {
  97. var handler = sinon.stub();
  98. $('#app-content-files').on('urlChanged', handler);
  99. App._onPopState({view: 'files', dir: '/somedir'});
  100. expect(handler.calledOnce).toEqual(true);
  101. expect(handler.getCall(0).args[0].view).toEqual('files');
  102. expect(handler.getCall(0).args[0].dir).toEqual('/somedir');
  103. });
  104. it('sends "show" event to current app and sets navigation', function() {
  105. var showHandlerFiles = sinon.stub();
  106. var showHandlerOther = sinon.stub();
  107. var hideHandlerFiles = sinon.stub();
  108. var hideHandlerOther = sinon.stub();
  109. $('#app-content-files').on('show', showHandlerFiles);
  110. $('#app-content-files').on('hide', hideHandlerFiles);
  111. $('#app-content-other').on('show', showHandlerOther);
  112. $('#app-content-other').on('hide', hideHandlerOther);
  113. App._onPopState({view: 'other', dir: '/somedir'});
  114. expect(showHandlerFiles.notCalled).toEqual(true);
  115. expect(hideHandlerFiles.calledOnce).toEqual(true);
  116. expect(showHandlerOther.calledOnce).toEqual(true);
  117. expect(hideHandlerOther.notCalled).toEqual(true);
  118. showHandlerFiles.reset();
  119. showHandlerOther.reset();
  120. hideHandlerFiles.reset();
  121. hideHandlerOther.reset();
  122. App._onPopState({view: 'files', dir: '/somedir'});
  123. expect(showHandlerFiles.calledOnce).toEqual(true);
  124. expect(hideHandlerFiles.notCalled).toEqual(true);
  125. expect(showHandlerOther.notCalled).toEqual(true);
  126. expect(hideHandlerOther.calledOnce).toEqual(true);
  127. expect(App.navigation.getActiveItem()).toEqual('files');
  128. expect($('#app-content-files').hasClass('hidden')).toEqual(false);
  129. expect($('#app-content-other').hasClass('hidden')).toEqual(true);
  130. });
  131. it('does not send "show" or "hide" event to current app when already visible', function() {
  132. var showHandler = sinon.stub();
  133. var hideHandler = sinon.stub();
  134. $('#app-content-files').on('show', showHandler);
  135. $('#app-content-files').on('hide', hideHandler);
  136. App._onPopState({view: 'files', dir: '/somedir'});
  137. expect(showHandler.notCalled).toEqual(true);
  138. expect(hideHandler.notCalled).toEqual(true);
  139. });
  140. it('state defaults to files app with root dir', function() {
  141. var handler = sinon.stub();
  142. parseUrlQueryStub.returns({});
  143. $('#app-content-files').on('urlChanged', handler);
  144. App._onPopState();
  145. expect(handler.calledOnce).toEqual(true);
  146. expect(handler.getCall(0).args[0].view).toEqual('files');
  147. expect(handler.getCall(0).args[0].dir).toEqual('/');
  148. });
  149. it('activates files app if invalid view is passed', function() {
  150. App._onPopState({view: 'invalid', dir: '/somedir'});
  151. expect(App.navigation.getActiveItem()).toEqual('files');
  152. expect($('#app-content-files').hasClass('hidden')).toEqual(false);
  153. });
  154. });
  155. describe('navigation', function() {
  156. it('switches the navigation item and panel visibility when onpopstate', function() {
  157. App._onPopState({view: 'other', dir: '/somedir'});
  158. expect(App.navigation.getActiveItem()).toEqual('other');
  159. expect($('#app-content-files').hasClass('hidden')).toEqual(true);
  160. expect($('#app-content-other').hasClass('hidden')).toEqual(false);
  161. expect($('li[data-id=files] > a').hasClass('active')).toEqual(false);
  162. expect($('li[data-id=other] > a').hasClass('active')).toEqual(true);
  163. App._onPopState({view: 'files', dir: '/somedir'});
  164. expect(App.navigation.getActiveItem()).toEqual('files');
  165. expect($('#app-content-files').hasClass('hidden')).toEqual(false);
  166. expect($('#app-content-other').hasClass('hidden')).toEqual(true);
  167. expect($('li[data-id=files] > a').hasClass('active')).toEqual(true);
  168. expect($('li[data-id=other] > a').hasClass('active')).toEqual(false);
  169. });
  170. it('clicking on navigation switches the panel visibility', function() {
  171. $('li[data-id=other] > a').click();
  172. expect(App.navigation.getActiveItem()).toEqual('other');
  173. expect($('#app-content-files').hasClass('hidden')).toEqual(true);
  174. expect($('#app-content-other').hasClass('hidden')).toEqual(false);
  175. expect($('li[data-id=files] > a').hasClass('active')).toEqual(false);
  176. expect($('li[data-id=other] > a').hasClass('active')).toEqual(true);
  177. $('li[data-id=files] > a').click();
  178. expect(App.navigation.getActiveItem()).toEqual('files');
  179. expect($('#app-content-files').hasClass('hidden')).toEqual(false);
  180. expect($('#app-content-other').hasClass('hidden')).toEqual(true);
  181. expect($('li[data-id=files] > a').hasClass('active')).toEqual(true);
  182. expect($('li[data-id=other] > a').hasClass('active')).toEqual(false);
  183. });
  184. it('clicking on navigation sends "show" and "urlChanged" event', function() {
  185. var handler = sinon.stub();
  186. var showHandler = sinon.stub();
  187. $('#app-content-other').on('urlChanged', handler);
  188. $('#app-content-other').on('show', showHandler);
  189. $('li[data-id=other] > a').click();
  190. expect(handler.calledOnce).toEqual(true);
  191. expect(handler.getCall(0).args[0].view).toEqual('other');
  192. expect(handler.getCall(0).args[0].dir).toEqual('/');
  193. expect(showHandler.calledOnce).toEqual(true);
  194. });
  195. it('clicking on activate navigation only sends "urlChanged" event', function() {
  196. var handler = sinon.stub();
  197. var showHandler = sinon.stub();
  198. $('#app-content-files').on('urlChanged', handler);
  199. $('#app-content-files').on('show', showHandler);
  200. $('li[data-id=files] > a').click();
  201. expect(handler.calledOnce).toEqual(true);
  202. expect(handler.getCall(0).args[0].view).toEqual('files');
  203. expect(handler.getCall(0).args[0].dir).toEqual('/');
  204. expect(showHandler.notCalled).toEqual(true);
  205. });
  206. });
  207. describe('viewer mode', function() {
  208. it('toggles the sidebar when viewer mode is enabled', function() {
  209. $('#app-content-files').trigger(
  210. new $.Event('changeViewerMode', {viewerModeEnabled: true}
  211. ));
  212. expect($('#app-navigation').hasClass('hidden')).toEqual(true);
  213. expect($('.app-files').hasClass('viewer-mode no-sidebar')).toEqual(true);
  214. $('#app-content-files').trigger(
  215. new $.Event('changeViewerMode', {viewerModeEnabled: false}
  216. ));
  217. expect($('#app-navigation').hasClass('hidden')).toEqual(false);
  218. expect($('.app-files').hasClass('viewer-mode no-sidebar')).toEqual(false);
  219. });
  220. });
  221. });
  222. });