/test/app/AppDataAttributeHandler.js

https://github.com/eduardolundgren/senna · JavaScript · 269 lines · 231 code · 37 blank · 1 comment · 1 complexity · 9490df9a723d4dd464f8c399f2f7922a MD5 · raw file

  1. 'use strict';
  2. import dom from 'metal-dom';
  3. import globals from '../../src/globals/globals';
  4. import AppDataAttributeHandler from '../../src/app/AppDataAttributeHandler';
  5. import Screen from '../../src/screen/Screen';
  6. describe('AppDataAttributeHandler', function() {
  7. before(() => {
  8. globals.document.body.setAttribute('data-senna', '');
  9. globals.window.senna = {
  10. Screen: Screen
  11. };
  12. // Prevent log messages from showing up in test output.
  13. sinon.stub(console, 'log');
  14. });
  15. after(() => {
  16. globals.document.body.removeAttribute('data-senna');
  17. delete globals.window.senna;
  18. console.log.restore();
  19. });
  20. it('should throw error when base element not specified', () => {
  21. assert.throws(() => {
  22. new AppDataAttributeHandler().handle();
  23. }, Error);
  24. });
  25. it('should throw error when base element not valid', () => {
  26. assert.throws(() => {
  27. var appDataAttributeHandler = new AppDataAttributeHandler();
  28. appDataAttributeHandler.setBaseElement({});
  29. appDataAttributeHandler.handle();
  30. }, Error);
  31. });
  32. it('should throw error when already handled', () => {
  33. assert.throws(() => {
  34. var appDataAttributeHandler = new AppDataAttributeHandler();
  35. appDataAttributeHandler.setBaseElement(globals.document.body);
  36. appDataAttributeHandler.handle();
  37. appDataAttributeHandler.handle();
  38. }, Error);
  39. });
  40. it('should not throw error when base element specified', () => {
  41. assert.doesNotThrow(() => {
  42. var appDataAttributeHandler = new AppDataAttributeHandler();
  43. appDataAttributeHandler.setBaseElement(globals.document.body);
  44. appDataAttributeHandler.handle();
  45. appDataAttributeHandler.dispose();
  46. });
  47. });
  48. it('should dispose internal app when disposed', () => {
  49. var appDataAttributeHandler = new AppDataAttributeHandler();
  50. appDataAttributeHandler.setBaseElement(globals.document.body);
  51. appDataAttributeHandler.handle();
  52. appDataAttributeHandler.dispose();
  53. assert.ok(appDataAttributeHandler.getApp().isDisposed());
  54. });
  55. it('should dispose when not handled', () => {
  56. assert.doesNotThrow(() => {
  57. var appDataAttributeHandler = new AppDataAttributeHandler();
  58. appDataAttributeHandler.dispose();
  59. });
  60. });
  61. it('should get app', () => {
  62. var appDataAttributeHandler = new AppDataAttributeHandler();
  63. appDataAttributeHandler.setBaseElement(globals.document.body);
  64. appDataAttributeHandler.handle();
  65. assert.ok(appDataAttributeHandler.getApp());
  66. appDataAttributeHandler.dispose();
  67. });
  68. it('should get base element', () => {
  69. var appDataAttributeHandler = new AppDataAttributeHandler();
  70. appDataAttributeHandler.setBaseElement(globals.document.body);
  71. assert.strictEqual(globals.document.body, appDataAttributeHandler.getBaseElement());
  72. });
  73. it('should add app surfaces from document', () => {
  74. enterDocumentSurfaceElement('surfaceId');
  75. var appDataAttributeHandler = new AppDataAttributeHandler();
  76. appDataAttributeHandler.setBaseElement(globals.document.body);
  77. appDataAttributeHandler.handle();
  78. assert.ok('surfaceId' in appDataAttributeHandler.getApp().surfaces);
  79. appDataAttributeHandler.dispose();
  80. exitDocumentSurfaceElement('surfaceId');
  81. });
  82. it('should adds random id to body without id when used as app surface', () => {
  83. globals.document.body.setAttribute('data-senna-surface', '');
  84. var appDataAttributeHandler = new AppDataAttributeHandler();
  85. appDataAttributeHandler.setBaseElement(globals.document.body);
  86. appDataAttributeHandler.handle();
  87. assert.ok(globals.document.body);
  88. appDataAttributeHandler.dispose();
  89. globals.document.body.removeAttribute('data-senna-surface');
  90. });
  91. it('should throw error when adding app surfaces from document missing id', () => {
  92. enterDocumentSurfaceElementMissingId('surfaceId');
  93. assert.throws(() => {
  94. var appDataAttributeHandler = new AppDataAttributeHandler();
  95. appDataAttributeHandler.setBaseElement(globals.document.body);
  96. appDataAttributeHandler.handle();
  97. }, Error);
  98. exitDocumentSurfaceElementMissingId('surfaceId');
  99. });
  100. it('should add default route if not found in document', () => {
  101. var appDataAttributeHandler = new AppDataAttributeHandler();
  102. appDataAttributeHandler.setBaseElement(globals.document.body);
  103. appDataAttributeHandler.handle();
  104. assert.ok(appDataAttributeHandler.getApp().hasRoutes());
  105. appDataAttributeHandler.dispose();
  106. });
  107. it('should add routes from document', () => {
  108. enterDocumentRouteElement('/path1');
  109. enterDocumentRouteElement('/path2');
  110. var appDataAttributeHandler = new AppDataAttributeHandler();
  111. appDataAttributeHandler.setBaseElement(globals.document.body);
  112. appDataAttributeHandler.handle();
  113. assert.strictEqual(2, appDataAttributeHandler.getApp().routes.length);
  114. appDataAttributeHandler.dispose();
  115. exitDocumentRouteElement('/path1');
  116. exitDocumentRouteElement('/path2');
  117. });
  118. it('should add routes from document with regex paths', () => {
  119. enterDocumentRouteElement('regex:[a-z]');
  120. var appDataAttributeHandler = new AppDataAttributeHandler();
  121. appDataAttributeHandler.setBaseElement(globals.document.body);
  122. appDataAttributeHandler.handle();
  123. assert.ok(appDataAttributeHandler.getApp().routes[0].getPath() instanceof RegExp);
  124. appDataAttributeHandler.dispose();
  125. exitDocumentRouteElement('regex:[a-z]');
  126. });
  127. it('should throw error when adding routes from document with missing screen type', () => {
  128. enterDocumentRouteElementMissingScreenType('/path');
  129. assert.throws(() => {
  130. var appDataAttributeHandler = new AppDataAttributeHandler();
  131. appDataAttributeHandler.setBaseElement(globals.document.body);
  132. appDataAttributeHandler.handle();
  133. }, Error);
  134. exitDocumentRouteElement('/path');
  135. });
  136. it('should throw error when adding routes from document with missing path', () => {
  137. enterDocumentRouteElementMissingPath();
  138. assert.throws(() => {
  139. var appDataAttributeHandler = new AppDataAttributeHandler();
  140. appDataAttributeHandler.setBaseElement(globals.document.body);
  141. appDataAttributeHandler.handle();
  142. }, Error);
  143. exitDocumentRouteElementMissingPath();
  144. });
  145. it('should set base path from data attribute', () => {
  146. globals.document.body.setAttribute('data-senna-base-path', '/base');
  147. var appDataAttributeHandler = new AppDataAttributeHandler();
  148. appDataAttributeHandler.setBaseElement(globals.document.body);
  149. appDataAttributeHandler.handle();
  150. assert.strictEqual('/base', appDataAttributeHandler.getApp().getBasePath());
  151. appDataAttributeHandler.dispose();
  152. globals.document.body.removeAttribute('data-senna-base-path');
  153. });
  154. it('should set link selector from data attribute', () => {
  155. globals.document.body.setAttribute('data-senna-link-selector', 'a');
  156. var appDataAttributeHandler = new AppDataAttributeHandler();
  157. appDataAttributeHandler.setBaseElement(globals.document.body);
  158. appDataAttributeHandler.handle();
  159. assert.strictEqual('a', appDataAttributeHandler.getApp().getLinkSelector());
  160. appDataAttributeHandler.dispose();
  161. globals.document.body.removeAttribute('data-senna-link-selector');
  162. });
  163. it('should set loading css class from data attribute', () => {
  164. globals.document.body.setAttribute('data-senna-loading-css-class', 'loading');
  165. var appDataAttributeHandler = new AppDataAttributeHandler();
  166. appDataAttributeHandler.setBaseElement(globals.document.body);
  167. appDataAttributeHandler.handle();
  168. assert.strictEqual('loading', appDataAttributeHandler.getApp().getLoadingCssClass());
  169. appDataAttributeHandler.dispose();
  170. globals.document.body.removeAttribute('data-senna-loading-css-class');
  171. });
  172. it('should set update scroll position to false from data attribute', () => {
  173. globals.document.body.setAttribute('data-senna-update-scroll-position', 'false');
  174. var appDataAttributeHandler = new AppDataAttributeHandler();
  175. appDataAttributeHandler.setBaseElement(globals.document.body);
  176. appDataAttributeHandler.handle();
  177. assert.strictEqual(false, appDataAttributeHandler.getApp().getUpdateScrollPosition());
  178. appDataAttributeHandler.dispose();
  179. globals.document.body.removeAttribute('data-senna-update-scroll-position');
  180. });
  181. it('should set update scroll position to true from data attribute', () => {
  182. globals.document.body.setAttribute('data-senna-update-scroll-position', 'true');
  183. var appDataAttributeHandler = new AppDataAttributeHandler();
  184. appDataAttributeHandler.setBaseElement(globals.document.body);
  185. appDataAttributeHandler.handle();
  186. assert.strictEqual(true, appDataAttributeHandler.getApp().getUpdateScrollPosition());
  187. appDataAttributeHandler.dispose();
  188. globals.document.body.removeAttribute('data-senna-update-scroll-position');
  189. });
  190. it('should dispatch app from data attribute', () => {
  191. globals.document.body.setAttribute('data-senna-dispatch', '');
  192. var appDataAttributeHandler = new AppDataAttributeHandler();
  193. appDataAttributeHandler.setBaseElement(globals.document.body);
  194. appDataAttributeHandler.handle();
  195. return appDataAttributeHandler.getApp().on('endNavigate', () => {
  196. appDataAttributeHandler.dispose();
  197. globals.document.body.removeAttribute('data-senna-dispatch');
  198. });
  199. });
  200. });
  201. function enterDocumentRouteElement(path) {
  202. dom.enterDocument('<link href="' + path + '" rel="senna-route" type="senna.Screen"></link>');
  203. return document.querySelector('link[href="' + path + '"]');
  204. }
  205. function enterDocumentRouteElementMissingPath() {
  206. dom.enterDocument('<link id="routeElementMissingPath" rel="senna-route" type="senna.Screen"></link>');
  207. return document.getElementById('routeElementMissingPath');
  208. }
  209. function enterDocumentRouteElementMissingScreenType(path) {
  210. dom.enterDocument('<link href="' + path + '" rel="senna-route"></link>');
  211. return document.querySelector('link[href="' + path + '"]');
  212. }
  213. function enterDocumentSurfaceElement(surfaceId) {
  214. dom.enterDocument('<div id="' + surfaceId + '" data-senna-surface></div>');
  215. return document.getElementById(surfaceId);
  216. }
  217. function enterDocumentSurfaceElementMissingId(surfaceId) {
  218. dom.enterDocument('<div data-id="' + surfaceId + '" data-senna-surface></div>');
  219. return document.getElementById(surfaceId);
  220. }
  221. function exitDocumentRouteElement(path) {
  222. return dom.exitDocument(document.querySelector('link[href="' + path + '"]'));
  223. }
  224. function exitDocumentRouteElementMissingPath() {
  225. return dom.exitDocument(document.getElementById('routeElementMissingPath'));
  226. }
  227. function exitDocumentSurfaceElement(surfaceId) {
  228. return dom.exitDocument(document.getElementById(surfaceId));
  229. }
  230. function exitDocumentSurfaceElementMissingId(surfaceId) {
  231. return dom.exitDocument(document.querySelector('[data-id="' + surfaceId + '"]'));
  232. }