display_utils_spec.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /**
  2. * @licstart The following is the entire license notice for the
  3. * Javascript code in this page
  4. *
  5. * Copyright 2019 Mozilla Foundation
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. *
  19. * @licend The above is the entire license notice for the
  20. * Javascript code in this page
  21. */
  22. "use strict";
  23. var _display_utils = require("../../display/display_utils");
  24. var _is_node = _interopRequireDefault(require("../../shared/is_node"));
  25. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
  26. function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
  27. function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
  28. function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
  29. function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
  30. describe('display_utils', function () {
  31. describe('DOMCanvasFactory', function () {
  32. var canvasFactory;
  33. beforeAll(function (done) {
  34. canvasFactory = new _display_utils.DOMCanvasFactory();
  35. done();
  36. });
  37. afterAll(function () {
  38. canvasFactory = null;
  39. });
  40. it('`create` should throw an error if the dimensions are invalid', function () {
  41. expect(function () {
  42. return canvasFactory.create(-1, 1);
  43. }).toThrow(new Error('Invalid canvas size'));
  44. expect(function () {
  45. return canvasFactory.create(1, -1);
  46. }).toThrow(new Error('Invalid canvas size'));
  47. });
  48. it('`create` should return a canvas if the dimensions are valid', function () {
  49. if ((0, _is_node["default"])()) {
  50. pending('Document is not supported in Node.js.');
  51. }
  52. var _canvasFactory$create = canvasFactory.create(20, 40),
  53. canvas = _canvasFactory$create.canvas,
  54. context = _canvasFactory$create.context;
  55. expect(canvas instanceof HTMLCanvasElement).toBe(true);
  56. expect(context instanceof CanvasRenderingContext2D).toBe(true);
  57. expect(canvas.width).toBe(20);
  58. expect(canvas.height).toBe(40);
  59. });
  60. it('`reset` should throw an error if no canvas is provided', function () {
  61. var canvasAndContext = {
  62. canvas: null,
  63. context: null
  64. };
  65. expect(function () {
  66. return canvasFactory.reset(canvasAndContext, 20, 40);
  67. }).toThrow(new Error('Canvas is not specified'));
  68. });
  69. it('`reset` should throw an error if the dimensions are invalid', function () {
  70. var canvasAndContext = {
  71. canvas: 'foo',
  72. context: 'bar'
  73. };
  74. expect(function () {
  75. return canvasFactory.reset(canvasAndContext, -1, 1);
  76. }).toThrow(new Error('Invalid canvas size'));
  77. expect(function () {
  78. return canvasFactory.reset(canvasAndContext, 1, -1);
  79. }).toThrow(new Error('Invalid canvas size'));
  80. });
  81. it('`reset` should alter the canvas/context if the dimensions are valid', function () {
  82. if ((0, _is_node["default"])()) {
  83. pending('Document is not supported in Node.js.');
  84. }
  85. var canvasAndContext = canvasFactory.create(20, 40);
  86. canvasFactory.reset(canvasAndContext, 60, 80);
  87. var canvas = canvasAndContext.canvas,
  88. context = canvasAndContext.context;
  89. expect(canvas instanceof HTMLCanvasElement).toBe(true);
  90. expect(context instanceof CanvasRenderingContext2D).toBe(true);
  91. expect(canvas.width).toBe(60);
  92. expect(canvas.height).toBe(80);
  93. });
  94. it('`destroy` should throw an error if no canvas is provided', function () {
  95. expect(function () {
  96. return canvasFactory.destroy({});
  97. }).toThrow(new Error('Canvas is not specified'));
  98. });
  99. it('`destroy` should clear the canvas/context', function () {
  100. if ((0, _is_node["default"])()) {
  101. pending('Document is not supported in Node.js.');
  102. }
  103. var canvasAndContext = canvasFactory.create(20, 40);
  104. canvasFactory.destroy(canvasAndContext);
  105. var canvas = canvasAndContext.canvas,
  106. context = canvasAndContext.context;
  107. expect(canvas).toBe(null);
  108. expect(context).toBe(null);
  109. });
  110. });
  111. describe('DOMSVGFactory', function () {
  112. var svgFactory;
  113. beforeAll(function (done) {
  114. svgFactory = new _display_utils.DOMSVGFactory();
  115. done();
  116. });
  117. afterAll(function () {
  118. svgFactory = null;
  119. });
  120. it('`create` should throw an error if the dimensions are invalid', function () {
  121. expect(function () {
  122. return svgFactory.create(-1, 0);
  123. }).toThrow(new Error('Invalid SVG dimensions'));
  124. expect(function () {
  125. return svgFactory.create(0, -1);
  126. }).toThrow(new Error('Invalid SVG dimensions'));
  127. });
  128. it('`create` should return an SVG element if the dimensions are valid', function () {
  129. if ((0, _is_node["default"])()) {
  130. pending('Document is not supported in Node.js.');
  131. }
  132. var svg = svgFactory.create(20, 40);
  133. expect(svg instanceof SVGSVGElement).toBe(true);
  134. expect(svg.getAttribute('version')).toBe('1.1');
  135. expect(svg.getAttribute('width')).toBe('20px');
  136. expect(svg.getAttribute('height')).toBe('40px');
  137. expect(svg.getAttribute('preserveAspectRatio')).toBe('none');
  138. expect(svg.getAttribute('viewBox')).toBe('0 0 20 40');
  139. });
  140. it('`createElement` should throw an error if the type is not a string', function () {
  141. expect(function () {
  142. return svgFactory.createElement(true);
  143. }).toThrow(new Error('Invalid SVG element type'));
  144. });
  145. it('`createElement` should return an SVG element if the type is valid', function () {
  146. if ((0, _is_node["default"])()) {
  147. pending('Document is not supported in Node.js.');
  148. }
  149. var svg = svgFactory.createElement('svg:rect');
  150. expect(svg instanceof SVGRectElement).toBe(true);
  151. });
  152. });
  153. describe('getFilenameFromUrl', function () {
  154. it('should get the filename from an absolute URL', function () {
  155. var url = 'https://server.org/filename.pdf';
  156. expect((0, _display_utils.getFilenameFromUrl)(url)).toEqual('filename.pdf');
  157. });
  158. it('should get the filename from a relative URL', function () {
  159. var url = '../../filename.pdf';
  160. expect((0, _display_utils.getFilenameFromUrl)(url)).toEqual('filename.pdf');
  161. });
  162. it('should get the filename from a URL with an anchor', function () {
  163. var url = 'https://server.org/filename.pdf#foo';
  164. expect((0, _display_utils.getFilenameFromUrl)(url)).toEqual('filename.pdf');
  165. });
  166. it('should get the filename from a URL with query parameters', function () {
  167. var url = 'https://server.org/filename.pdf?foo=bar';
  168. expect((0, _display_utils.getFilenameFromUrl)(url)).toEqual('filename.pdf');
  169. });
  170. });
  171. describe('isValidFetchUrl', function () {
  172. it('handles invalid Fetch URLs', function () {
  173. expect((0, _display_utils.isValidFetchUrl)(null)).toEqual(false);
  174. expect((0, _display_utils.isValidFetchUrl)(100)).toEqual(false);
  175. expect((0, _display_utils.isValidFetchUrl)('foo')).toEqual(false);
  176. expect((0, _display_utils.isValidFetchUrl)('/foo', 100)).toEqual(false);
  177. });
  178. it('handles relative Fetch URLs', function () {
  179. expect((0, _display_utils.isValidFetchUrl)('/foo', 'file://www.example.com')).toEqual(false);
  180. expect((0, _display_utils.isValidFetchUrl)('/foo', 'http://www.example.com')).toEqual(true);
  181. });
  182. it('handles unsupported Fetch protocols', function () {
  183. expect((0, _display_utils.isValidFetchUrl)('file://www.example.com')).toEqual(false);
  184. expect((0, _display_utils.isValidFetchUrl)('ftp://www.example.com')).toEqual(false);
  185. });
  186. it('handles supported Fetch protocols', function () {
  187. expect((0, _display_utils.isValidFetchUrl)('http://www.example.com')).toEqual(true);
  188. expect((0, _display_utils.isValidFetchUrl)('https://www.example.com')).toEqual(true);
  189. });
  190. });
  191. describe('PDFDateString', function () {
  192. describe('toDateObject', function () {
  193. it('converts PDF date strings to JavaScript `Date` objects', function () {
  194. var expectations = {
  195. undefined: null,
  196. "null": null,
  197. 42: null,
  198. '2019': null,
  199. 'D2019': null,
  200. 'D:': null,
  201. 'D:201': null,
  202. 'D:2019': new Date(Date.UTC(2019, 0, 1, 0, 0, 0)),
  203. 'D:20190': new Date(Date.UTC(2019, 0, 1, 0, 0, 0)),
  204. 'D:201900': new Date(Date.UTC(2019, 0, 1, 0, 0, 0)),
  205. 'D:201913': new Date(Date.UTC(2019, 0, 1, 0, 0, 0)),
  206. 'D:201902': new Date(Date.UTC(2019, 1, 1, 0, 0, 0)),
  207. 'D:2019020': new Date(Date.UTC(2019, 1, 1, 0, 0, 0)),
  208. 'D:20190200': new Date(Date.UTC(2019, 1, 1, 0, 0, 0)),
  209. 'D:20190232': new Date(Date.UTC(2019, 1, 1, 0, 0, 0)),
  210. 'D:20190203': new Date(Date.UTC(2019, 1, 3, 0, 0, 0)),
  211. 'D:20190431': new Date(Date.UTC(2019, 4, 1, 0, 0, 0)),
  212. 'D:201902030': new Date(Date.UTC(2019, 1, 3, 0, 0, 0)),
  213. 'D:2019020300': new Date(Date.UTC(2019, 1, 3, 0, 0, 0)),
  214. 'D:2019020324': new Date(Date.UTC(2019, 1, 3, 0, 0, 0)),
  215. 'D:2019020304': new Date(Date.UTC(2019, 1, 3, 4, 0, 0)),
  216. 'D:20190203040': new Date(Date.UTC(2019, 1, 3, 4, 0, 0)),
  217. 'D:201902030400': new Date(Date.UTC(2019, 1, 3, 4, 0, 0)),
  218. 'D:201902030460': new Date(Date.UTC(2019, 1, 3, 4, 0, 0)),
  219. 'D:201902030405': new Date(Date.UTC(2019, 1, 3, 4, 5, 0)),
  220. 'D:2019020304050': new Date(Date.UTC(2019, 1, 3, 4, 5, 0)),
  221. 'D:20190203040500': new Date(Date.UTC(2019, 1, 3, 4, 5, 0)),
  222. 'D:20190203040560': new Date(Date.UTC(2019, 1, 3, 4, 5, 0)),
  223. 'D:20190203040506': new Date(Date.UTC(2019, 1, 3, 4, 5, 6)),
  224. 'D:20190203040506F': new Date(Date.UTC(2019, 1, 3, 4, 5, 6)),
  225. 'D:20190203040506Z': new Date(Date.UTC(2019, 1, 3, 4, 5, 6)),
  226. 'D:20190203040506-': new Date(Date.UTC(2019, 1, 3, 4, 5, 6)),
  227. 'D:20190203040506+': new Date(Date.UTC(2019, 1, 3, 4, 5, 6)),
  228. 'D:20190203040506+\'': new Date(Date.UTC(2019, 1, 3, 4, 5, 6)),
  229. 'D:20190203040506+0': new Date(Date.UTC(2019, 1, 3, 4, 5, 6)),
  230. 'D:20190203040506+01': new Date(Date.UTC(2019, 1, 3, 3, 5, 6)),
  231. 'D:20190203040506+00\'': new Date(Date.UTC(2019, 1, 3, 4, 5, 6)),
  232. 'D:20190203040506+24\'': new Date(Date.UTC(2019, 1, 3, 4, 5, 6)),
  233. 'D:20190203040506+01\'': new Date(Date.UTC(2019, 1, 3, 3, 5, 6)),
  234. 'D:20190203040506+01\'0': new Date(Date.UTC(2019, 1, 3, 3, 5, 6)),
  235. 'D:20190203040506+01\'00': new Date(Date.UTC(2019, 1, 3, 3, 5, 6)),
  236. 'D:20190203040506+01\'60': new Date(Date.UTC(2019, 1, 3, 3, 5, 6)),
  237. 'D:20190203040506+0102': new Date(Date.UTC(2019, 1, 3, 3, 3, 6)),
  238. 'D:20190203040506+01\'02': new Date(Date.UTC(2019, 1, 3, 3, 3, 6)),
  239. 'D:20190203040506+01\'02\'': new Date(Date.UTC(2019, 1, 3, 3, 3, 6)),
  240. 'D:20190203040506+05\'07': new Date(Date.UTC(2019, 1, 2, 22, 58, 6))
  241. };
  242. for (var _i = 0, _Object$entries = Object.entries(expectations); _i < _Object$entries.length; _i++) {
  243. var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
  244. input = _Object$entries$_i[0],
  245. expectation = _Object$entries$_i[1];
  246. var result = _display_utils.PDFDateString.toDateObject(input);
  247. if (result) {
  248. expect(result.getTime()).toEqual(expectation.getTime());
  249. } else {
  250. expect(result).toEqual(expectation);
  251. }
  252. }
  253. });
  254. });
  255. });
  256. });