1
0

detailsviewSpec.js 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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.DetailsView tests', function() {
  22. var detailsView;
  23. beforeEach(function() {
  24. detailsView = new OCA.Files.DetailsView();
  25. });
  26. afterEach(function() {
  27. detailsView.remove();
  28. detailsView = undefined;
  29. });
  30. it('renders itself empty when nothing registered', function() {
  31. detailsView.render();
  32. expect(detailsView.$el.find('.detailFileInfoContainer').length).toEqual(1);
  33. expect(detailsView.$el.find('.tabsContainer').length).toEqual(1);
  34. });
  35. describe('file info detail view', function() {
  36. it('renders registered view', function() {
  37. var testView = new OCA.Files.DetailFileInfoView();
  38. var testView2 = new OCA.Files.DetailFileInfoView();
  39. detailsView.addDetailView(testView);
  40. detailsView.addDetailView(testView2);
  41. detailsView.render();
  42. expect(detailsView.$el.find('.detailFileInfoContainer .detailFileInfoView').length).toEqual(2);
  43. });
  44. it('updates registered tabs when fileinfo is updated', function() {
  45. var viewRenderStub = sinon.stub(OCA.Files.DetailFileInfoView.prototype, 'render');
  46. var testView = new OCA.Files.DetailFileInfoView();
  47. var testView2 = new OCA.Files.DetailFileInfoView();
  48. detailsView.addDetailView(testView);
  49. detailsView.addDetailView(testView2);
  50. detailsView.render();
  51. var fileInfo = {id: 5, name: 'test.txt'};
  52. viewRenderStub.reset();
  53. detailsView.setFileInfo(fileInfo);
  54. expect(testView.getFileInfo()).toEqual(fileInfo);
  55. expect(testView2.getFileInfo()).toEqual(fileInfo);
  56. expect(viewRenderStub.callCount).toEqual(2);
  57. viewRenderStub.restore();
  58. });
  59. });
  60. describe('tabs', function() {
  61. var testView, testView2;
  62. beforeEach(function() {
  63. testView = new OCA.Files.DetailTabView({id: 'test1'});
  64. testView2 = new OCA.Files.DetailTabView({id: 'test2'});
  65. detailsView.addTabView(testView);
  66. detailsView.addTabView(testView2);
  67. detailsView.render();
  68. });
  69. it('initially renders only the selected tab', function() {
  70. expect(detailsView.$el.find('.tab').length).toEqual(1);
  71. expect(detailsView.$el.find('.tab').attr('id')).toEqual('test1');
  72. });
  73. it('updates tab model and rerenders on-demand as soon as it gets selected', function() {
  74. var tab1RenderStub = sinon.stub(testView, 'render');
  75. var tab2RenderStub = sinon.stub(testView2, 'render');
  76. var fileInfo1 = new OCA.Files.FileInfoModel({id: 5, name: 'test.txt'});
  77. var fileInfo2 = new OCA.Files.FileInfoModel({id: 8, name: 'test2.txt'});
  78. detailsView.setFileInfo(fileInfo1);
  79. // first tab renders, not the second one
  80. expect(tab1RenderStub.calledOnce).toEqual(true);
  81. expect(tab2RenderStub.notCalled).toEqual(true);
  82. // info got set only to the first visible tab
  83. expect(testView.getFileInfo()).toEqual(fileInfo1);
  84. expect(testView2.getFileInfo()).toBeUndefined();
  85. // select second tab for first render
  86. detailsView.$el.find('.tabHeader').eq(1).click();
  87. // second tab got rendered
  88. expect(tab2RenderStub.calledOnce).toEqual(true);
  89. expect(testView2.getFileInfo()).toEqual(fileInfo1);
  90. // select the first tab again
  91. detailsView.$el.find('.tabHeader').eq(0).click();
  92. // no re-render
  93. expect(tab1RenderStub.calledOnce).toEqual(true);
  94. expect(tab2RenderStub.calledOnce).toEqual(true);
  95. tab1RenderStub.reset();
  96. tab2RenderStub.reset();
  97. // switch to another file
  98. detailsView.setFileInfo(fileInfo2);
  99. // only the visible tab was updated and rerendered
  100. expect(tab1RenderStub.calledOnce).toEqual(true);
  101. expect(testView.getFileInfo()).toEqual(fileInfo2);
  102. // second/invisible tab still has old info, not rerendered
  103. expect(tab2RenderStub.notCalled).toEqual(true);
  104. expect(testView2.getFileInfo()).toEqual(fileInfo1);
  105. // reselect the second one
  106. detailsView.$el.find('.tabHeader').eq(1).click();
  107. // second tab becomes visible, updated and rendered
  108. expect(testView2.getFileInfo()).toEqual(fileInfo2);
  109. expect(tab2RenderStub.calledOnce).toEqual(true);
  110. tab1RenderStub.restore();
  111. tab2RenderStub.restore();
  112. });
  113. it('selects the first tab by default', function() {
  114. expect(detailsView.$el.find('.tabHeader').eq(0).hasClass('selected')).toEqual(true);
  115. expect(detailsView.$el.find('.tabHeader').eq(1).hasClass('selected')).toEqual(false);
  116. expect(detailsView.$el.find('.tab').eq(0).hasClass('hidden')).toEqual(false);
  117. expect(detailsView.$el.find('.tab').eq(1).length).toEqual(0);
  118. });
  119. it('switches the current tab when clicking on tab header', function() {
  120. detailsView.$el.find('.tabHeader').eq(1).click();
  121. expect(detailsView.$el.find('.tabHeader').eq(0).hasClass('selected')).toEqual(false);
  122. expect(detailsView.$el.find('.tabHeader').eq(1).hasClass('selected')).toEqual(true);
  123. expect(detailsView.$el.find('.tab').eq(0).hasClass('hidden')).toEqual(true);
  124. expect(detailsView.$el.find('.tab').eq(1).hasClass('hidden')).toEqual(false);
  125. });
  126. describe('tab visibility', function() {
  127. beforeEach(function() {
  128. detailsView.remove();
  129. detailsView = new OCA.Files.DetailsView();
  130. });
  131. it('does not display tab headers when only one tab exists', function() {
  132. testView = new OCA.Files.DetailTabView({id: 'test1'});
  133. detailsView.addTabView(testView);
  134. detailsView.render();
  135. expect(detailsView.$el.find('.tabHeaders').hasClass('hidden')).toEqual(true);
  136. expect(detailsView.$el.find('.tabHeader').length).toEqual(1);
  137. });
  138. it('does not display tab that do not pass visibility check', function() {
  139. testView = new OCA.Files.DetailTabView({id: 'test1'});
  140. testView.canDisplay = sinon.stub().returns(false);
  141. testView2 = new OCA.Files.DetailTabView({id: 'test2'});
  142. var testView3 = new OCA.Files.DetailTabView({id: 'test3'});
  143. detailsView.addTabView(testView);
  144. detailsView.addTabView(testView2);
  145. detailsView.addTabView(testView3);
  146. var fileInfo = {id: 5, name: 'test.txt'};
  147. detailsView.setFileInfo(fileInfo);
  148. expect(testView.canDisplay.calledOnce).toEqual(true);
  149. expect(testView.canDisplay.calledWith(fileInfo)).toEqual(true);
  150. expect(detailsView.$el.find('.tabHeaders').hasClass('hidden')).toEqual(false);
  151. expect(detailsView.$el.find('.tabHeader[data-tabid=test1]').hasClass('hidden')).toEqual(true);
  152. expect(detailsView.$el.find('.tabHeader[data-tabid=test2]').hasClass('hidden')).toEqual(false);
  153. expect(detailsView.$el.find('.tabHeader[data-tabid=test3]').hasClass('hidden')).toEqual(false);
  154. });
  155. it('does not show tab headers if only one header is visible due to visibility check', function() {
  156. testView = new OCA.Files.DetailTabView({id: 'test1'});
  157. testView.canDisplay = sinon.stub().returns(false);
  158. testView2 = new OCA.Files.DetailTabView({id: 'test2'});
  159. detailsView.addTabView(testView);
  160. detailsView.addTabView(testView2);
  161. var fileInfo = {id: 5, name: 'test.txt'};
  162. detailsView.setFileInfo(fileInfo);
  163. expect(testView.canDisplay.calledOnce).toEqual(true);
  164. expect(testView.canDisplay.calledWith(fileInfo)).toEqual(true);
  165. expect(detailsView.$el.find('.tabHeaders').hasClass('hidden')).toEqual(true);
  166. expect(detailsView.$el.find('.tabHeader[data-tabid=test1]').hasClass('hidden')).toEqual(true);
  167. expect(detailsView.$el.find('.tabHeader[data-tabid=test2]').hasClass('hidden')).toEqual(false);
  168. });
  169. it('deselects the current tab if a model update does not pass the visibility check', function() {
  170. testView = new OCA.Files.DetailTabView({id: 'test1'});
  171. testView.canDisplay = function(fileInfo) {
  172. return fileInfo.mimetype !== 'httpd/unix-directory';
  173. };
  174. testView2 = new OCA.Files.DetailTabView({id: 'test2'});
  175. detailsView.addTabView(testView);
  176. detailsView.addTabView(testView2);
  177. var fileInfo = {id: 5, name: 'test.txt', mimetype: 'text/plain'};
  178. detailsView.setFileInfo(fileInfo);
  179. expect(detailsView.$el.find('.tabHeader[data-tabid=test1]').hasClass('selected')).toEqual(true);
  180. expect(detailsView.$el.find('.tabHeader[data-tabid=test2]').hasClass('selected')).toEqual(false);
  181. detailsView.setFileInfo({id: 10, name: 'folder', mimetype: 'httpd/unix-directory'});
  182. expect(detailsView.$el.find('.tabHeader[data-tabid=test1]').hasClass('selected')).toEqual(false);
  183. expect(detailsView.$el.find('.tabHeader[data-tabid=test2]').hasClass('selected')).toEqual(true);
  184. });
  185. });
  186. it('sorts by order and then label', function() {
  187. detailsView.remove();
  188. detailsView = new OCA.Files.DetailsView();
  189. detailsView.addTabView(new OCA.Files.DetailTabView({id: 'abc', order: 20}));
  190. detailsView.addTabView(new OCA.Files.DetailTabView({id: 'def', order: 10}));
  191. detailsView.addTabView(new OCA.Files.DetailTabView({id: 'jkl'}));
  192. detailsView.addTabView(new OCA.Files.DetailTabView({id: 'ghi'}));
  193. detailsView.render();
  194. var tabs = detailsView.$el.find('.tabHeader').map(function() {
  195. return $(this).attr('data-tabid');
  196. }).toArray();
  197. expect(tabs).toEqual(['ghi', 'jkl', 'def', 'abc']);
  198. });
  199. });
  200. });