private.tests.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. /*global _flashState:true, _currentElement:true, _copyTarget:true, _extend, _getStyle, _removeClass, _addClass, _vars, _cacheBust, _extractDomain, _determineScriptAccess, _mapClipDataToFlash, _mapClipResultsFromFlash, _createEvent, _preprocessEvent, _getRelatedTarget, _shouldPerformAsync, _dispatchCallback, _detectFlashSupport */
  2. (function(module, test) {
  3. "use strict";
  4. var mimeType, ax, flashState;
  5. module("core/private.js unit tests - utils");
  6. test("`_getStyle` returns computed styles", function(assert) {
  7. assert.expect(5);
  8. // Arrange
  9. var pointerEl = $("a.no_cursor_style")[0];
  10. var nonPointerEl = $("a.no_pointer_anchor")[0];
  11. var zIndexAutoEl = $(".zindex-auto")[0];
  12. var clipButtonEl = $("#d_clip_button")[0];
  13. var bigBorderEl = $(".big-border")[0];
  14. // Act
  15. var pointerElComputedCursor = _getStyle(pointerEl, "cursor");
  16. var nonPointerElComputedCursor = _getStyle(nonPointerEl, "cursor");
  17. var zIndexAutoElComputedZIndex = _getStyle(zIndexAutoEl, "z-index");
  18. var clipButtonElComputedBorderLeftWidth = _getStyle(clipButtonEl, "border-left-width");
  19. var bigBorderElComputedBorderLeftWith = _getStyle(bigBorderEl, "border-left-width");
  20. // Assert
  21. assert.strictEqual(pointerElComputedCursor, "pointer");
  22. assert.notStrictEqual(nonPointerElComputedCursor, "pointer");
  23. // Returns 0 in IE7, "auto" everywhere else
  24. assert.strictEqual(/^(?:auto|0)$/.test(zIndexAutoElComputedZIndex), true);
  25. // This varies between "0px" and "3px" depending on the browser (WAT?)
  26. assert.strictEqual(/^[0-3]px$/.test(clipButtonElComputedBorderLeftWidth), true);
  27. assert.strictEqual(bigBorderElComputedBorderLeftWith, "10px");
  28. });
  29. test("`_removeClass` removes classes from element", function(assert) {
  30. assert.expect(5);
  31. // Arrange
  32. var div = $("<div></div>").addClass("class1 class-2 class_3")[0];
  33. // Act & Assert
  34. _removeClass(div, "class1");
  35. assert.strictEqual(div.className, "class-2 class_3");
  36. _removeClass(div, "classd");
  37. assert.strictEqual(div.className, "class-2 class_3");
  38. _removeClass(div, "class-2");
  39. assert.strictEqual(div.className, "class_3");
  40. _removeClass(div, "class_3");
  41. assert.strictEqual(div.className, "");
  42. _removeClass(div, "class-3");
  43. assert.strictEqual(div.className, "");
  44. div = null;
  45. });
  46. test("`_removeClass` doesn't remove partial class names", function(assert) {
  47. assert.expect(3);
  48. // Arrange
  49. var div = $("<div></div>").addClass("class1 class-2 class_3")[0];
  50. // Act & Assert
  51. _removeClass(div, "ass");
  52. assert.strictEqual(div.className, "class1 class-2 class_3");
  53. _removeClass(div, "-2");
  54. assert.strictEqual(div.className, "class1 class-2 class_3");
  55. _removeClass(div, "_3");
  56. assert.strictEqual(div.className, "class1 class-2 class_3");
  57. div = null;
  58. });
  59. test("`_addClass` adds a class name", function(assert) {
  60. assert.expect(4);
  61. // Arrange
  62. var div = $("<div></div>")[0];
  63. // Act & Assert
  64. _addClass(div, "class1");
  65. assert.strictEqual(div.className, "class1");
  66. _addClass(div, "class-2");
  67. assert.strictEqual(div.className, "class1 class-2");
  68. _addClass(div, "class_3");
  69. assert.strictEqual(div.className, "class1 class-2 class_3");
  70. _addClass(div, "class_3");
  71. assert.strictEqual(div.className, "class1 class-2 class_3");
  72. div = null;
  73. });
  74. test("`_vars` builds FlashVars", function(assert) {
  75. assert.expect(6);
  76. // Arrange
  77. var clipOptionsEmpty = {};
  78. var clipOptionsTrustedDomains = {
  79. trustedDomains: ["*"]
  80. };
  81. var clipOptionsEnhancedClipboardFalse = {
  82. forceEnhancedClipboard: false
  83. };
  84. var clipOptionsEnhancedClipboardTrue = {
  85. forceEnhancedClipboard: true
  86. };
  87. var clipOptionsTrustedDomainsPlusEnhancedClipboardFalse = {
  88. trustedDomains: ["*"],
  89. forceEnhancedClipboard: false
  90. };
  91. var clipOptionsTrustedDomainsPlusEnhancedClipboardTrue = {
  92. trustedDomains: ["*"],
  93. forceEnhancedClipboard: true
  94. };
  95. // Act & Assert
  96. assert.strictEqual(_vars(clipOptionsEmpty), "");
  97. assert.strictEqual(_vars(clipOptionsTrustedDomains), "trustedOrigins=*");
  98. assert.strictEqual(_vars(clipOptionsEnhancedClipboardFalse), "");
  99. assert.strictEqual(_vars(clipOptionsEnhancedClipboardTrue), "forceEnhancedClipboard=true");
  100. assert.strictEqual(_vars(clipOptionsTrustedDomainsPlusEnhancedClipboardFalse), "trustedOrigins=*");
  101. assert.strictEqual(_vars(clipOptionsTrustedDomainsPlusEnhancedClipboardTrue), "trustedOrigins=*&forceEnhancedClipboard=true");
  102. });
  103. test("`_cacheBust` adds cache-buster appropriately", function(assert) {
  104. assert.expect(2);
  105. // Arrange
  106. var pathWithoutQuery = "path.com/z.swf";
  107. var pathWithQuery = "path.com/z.swf?q=jon";
  108. // Act & Assert
  109. assert.strictEqual(_cacheBust(pathWithoutQuery).indexOf("?noCache="), 0);
  110. assert.strictEqual(_cacheBust(pathWithQuery).indexOf("&noCache="), 0);
  111. });
  112. test("`_cacheBust` can be disabled", function(assert) {
  113. assert.expect(2);
  114. // Arrange
  115. var pathWithoutQuery = "path.com/z.swf";
  116. var pathWithQuery = "path.com/z.swf?q=jon";
  117. var options = {
  118. cacheBust: false
  119. };
  120. // Act & Assert
  121. assert.strictEqual(_cacheBust(pathWithoutQuery, options), "");
  122. assert.strictEqual(_cacheBust(pathWithQuery, options), "");
  123. });
  124. test("`_extractDomain` extracts domains from origins and URLs", function(assert) {
  125. assert.expect(20);
  126. // Arrange
  127. var inputToExpectedMap = {
  128. "": null,
  129. " ": null,
  130. "ZeroClipboard.swf": null,
  131. "js/ZeroClipboard.swf": null,
  132. "/js/ZeroClipboard.swf": null,
  133. "/zeroclipboard/zeroclipboard/": null,
  134. "zeroclipboard/zeroclipboard/": null,
  135. "*": "*",
  136. "github.com": "github.com",
  137. "http://github.com": "github.com",
  138. "https://github.com": "github.com",
  139. "github.com:80": "github.com:80",
  140. "http://github.com:80": "github.com:80",
  141. "https://github.com:443": "github.com:443",
  142. "http://github.com/zeroclipboard/zeroclipboard/": "github.com",
  143. "https://github.com/zeroclipboard/zeroclipboard/": "github.com",
  144. "http://github.com:80/zeroclipboard/zeroclipboard/": "github.com:80",
  145. "https://github.com:443/zeroclipboard/zeroclipboard/": "github.com:443"
  146. };
  147. // Act & Assert
  148. assert.strictEqual(_extractDomain(undefined), null, "Processing: `undefined`");
  149. assert.strictEqual(_extractDomain(null), null, "Processing: `null`");
  150. for (var originOrUrl in inputToExpectedMap) {
  151. if (inputToExpectedMap.hasOwnProperty(originOrUrl)) {
  152. assert.strictEqual(_extractDomain(originOrUrl), inputToExpectedMap[originOrUrl], "Processing: \"" + originOrUrl + "\"");
  153. }
  154. }
  155. });
  156. test("`_determineScriptAccess` determines the appropriate script access level", function(assert) {
  157. // Arrange
  158. var i, len, tmp;
  159. var currentDomain = window.location.host || "localhost";
  160. var _globalConfig = {
  161. swfPath: "ZeroClipboard.swf",
  162. trustedDomains: [currentDomain]
  163. };
  164. var inputToExpectedMap = [
  165. // Same-domain SWF
  166. { args: [currentDomain, _globalConfig], result: "sameDomain" },
  167. { args: [currentDomain, _extend({}, _globalConfig, { trustedDomains: [] })], result: "never" },
  168. { args: [currentDomain, _extend({}, _globalConfig, { trustedDomains: ["*"] })], result: "always" },
  169. { args: [currentDomain, _extend({}, _globalConfig, { trustedDomains: [currentDomain, "otherDomain.com"] })], result: "always" },
  170. { args: [currentDomain, _extend({}, _globalConfig, { trustedDomains: ["otherDomain.com"] })], result: "never" },
  171. // Cross-domain SWF
  172. { args: [currentDomain, _extend({}, _globalConfig, { swfPath: "//otherDomain.com/ZeroClipboard.swf" })], result: "always" },
  173. { args: [currentDomain, _extend({}, _globalConfig, { swfPath: "//otherDomain.com/ZeroClipboard.swf", trustedDomains: [] })], result: "never" },
  174. { args: [currentDomain, _extend({}, _globalConfig, { swfPath: "//otherDomain.com/ZeroClipboard.swf", trustedDomains: ["*"] })], result: "always" },
  175. { args: [currentDomain, _extend({}, _globalConfig, { swfPath: "//otherDomain.com/ZeroClipboard.swf", trustedDomains: [currentDomain, "otherDomain.com"] })], result: "always" }
  176. ];
  177. // Act & Assert
  178. assert.expect(9);
  179. for (i = 0, len = inputToExpectedMap.length; i < len; i++) {
  180. tmp = inputToExpectedMap[i];
  181. assert.strictEqual(_determineScriptAccess.apply(this, tmp.args), tmp.result, "Processing: " + JSON.stringify(tmp));
  182. }
  183. });
  184. test("`_mapClipDataToFlash` works", function(assert) {
  185. assert.expect(1);
  186. // Arrange
  187. var clipData = {
  188. "text/plain": "Zero",
  189. "text/html": "<b>Zero</b>"
  190. };
  191. var expectedOutput = {
  192. data: {
  193. "text": "Zero",
  194. "html": "<b>Zero</b>"
  195. },
  196. formatMap: {
  197. "text": "text/plain",
  198. "html": "text/html"
  199. }
  200. };
  201. // Act
  202. var actual = _mapClipDataToFlash(clipData);
  203. // Assert
  204. assert.deepEqual(actual, expectedOutput, "Converted keys to Flash-friendly names and provided a format map");
  205. });
  206. test("`_mapClipResultsFromFlash` works", function(assert) {
  207. assert.expect(2);
  208. // Arrange
  209. var clipResults = {
  210. type: "aftercopy",
  211. success: {
  212. "text": true,
  213. "html": false
  214. },
  215. data: {
  216. "text": "Zero",
  217. "html": "<b>Zero</b>"
  218. }
  219. };
  220. var formatMap = {
  221. "text": "text/plain",
  222. "html": "text/html"
  223. };
  224. var expectedOutput = {
  225. type: "aftercopy",
  226. success: {
  227. "text/plain": true,
  228. "text/html": false
  229. },
  230. data: {
  231. "text/plain": "Zero",
  232. "text/html": "<b>Zero</b>"
  233. }
  234. };
  235. // Act & Assert
  236. var thisWontChange = _mapClipResultsFromFlash(clipResults, null);
  237. assert.deepEqual(thisWontChange, clipResults, "Should return the original object if it cannot map it");
  238. // Act & Assert
  239. var revisedClipResults = _mapClipResultsFromFlash(clipResults, formatMap);
  240. assert.deepEqual(revisedClipResults, expectedOutput, "Should reverse the key mapping process");
  241. });
  242. test("`_createEvent` works", function(assert) {
  243. assert.expect(2);
  244. var actual = _createEvent("ready");
  245. assert.strictEqual(typeof actual === "object" && actual != null, true, "Returns non-null object");
  246. assert.strictEqual(actual.type, "ready", "Object has a `type` property of 'ready'");
  247. // etc.
  248. });
  249. // Tests fix for: https://github.com/zeroclipboard/zeroclipboard/issues/467
  250. test("`_copyTarget` element is handled appropriately", function(assert) {
  251. assert.expect(18);
  252. // Arrange
  253. var el1 = $("#d_clip_button")[0];
  254. var el2 = $("#goodTargetId")[0];
  255. _currentElement = el1;
  256. _copyTarget = null;
  257. // Act
  258. var evt = _createEvent("beforecopy");
  259. _preprocessEvent(evt);
  260. // Assert
  261. assert.strictEqual(_currentElement, el1, "`_currentElement` is 'el1'");
  262. assert.strictEqual(_copyTarget, el1, "`_copyTarget` is 'el1'");
  263. assert.strictEqual(evt.target, el1, "`beforecopy` target is 'el1'");
  264. // Act some more
  265. _currentElement = el2;
  266. evt = _createEvent("copy");
  267. _preprocessEvent(evt);
  268. // Assert some more
  269. assert.strictEqual(_currentElement, el2, "`_currentElement` is 'el2'");
  270. assert.strictEqual(_copyTarget, el1, "`_copyTarget` is 'el1'");
  271. assert.strictEqual(evt.target, el1, "`copy` target is 'el1'");
  272. // Act some more: interruption due to mouse movement (only happens in Firefox,
  273. // though similar issues occur in Chrome for Windows if the user clicks on
  274. // another clipped element)
  275. evt = _createEvent("_mouseover");
  276. _preprocessEvent(evt);
  277. // Assert some more
  278. assert.strictEqual(_currentElement, el2, "`_currentElement` is 'el2'");
  279. assert.strictEqual(_copyTarget, el1, "`_copyTarget` is 'el1'");
  280. assert.strictEqual(evt.target, el2, "`_mouseover` target is 'el2'");
  281. // Act some more
  282. evt = _createEvent("aftercopy");
  283. _preprocessEvent(evt);
  284. // Assert some more
  285. assert.strictEqual(_currentElement, el2, "`_currentElement` is 'el2'");
  286. assert.strictEqual(_copyTarget, el1, "`_copyTarget` is 'el1'");
  287. assert.strictEqual(evt.target, el1, "`aftercopy` target is 'el1'");
  288. // Act some more
  289. evt = _createEvent("_click");
  290. // Assert some more
  291. assert.strictEqual(_currentElement, el2, "`_currentElement` is 'el2'");
  292. assert.strictEqual(_copyTarget, el1, "`_copyTarget` is 'el1'");
  293. assert.strictEqual(evt.target, el1, "`_click` target is 'el1'");
  294. // Act some more
  295. _preprocessEvent(evt);
  296. // Assert some more
  297. assert.strictEqual(_currentElement, el2, "`_currentElement` is 'el2'");
  298. assert.strictEqual(_copyTarget, null, "`_copyTarget` is `null`");
  299. assert.strictEqual(evt.target, el1, "`_click` target is 'el1'");
  300. // Reset
  301. _currentElement = _copyTarget = el1 = el2 = null;
  302. });
  303. test("`_getRelatedTarget` works", function(assert) {
  304. assert.expect(4);
  305. var relTarget = $("#relTargetId")[0];
  306. var goodTarget = $("#goodTargetId")[0];
  307. var badTarget1 = $("#badTargetId1")[0];
  308. var badTarget2 = $("#badTargetId2")[0];
  309. assert.notEqual(relTarget, null, "The related target is `null`");
  310. assert.strictEqual(_getRelatedTarget(goodTarget), relTarget, "Element with `data-clipboard-target` returns `null`");
  311. assert.strictEqual(_getRelatedTarget(badTarget1), null, "Element with `data-clipboard-target` that doesn't much any elements returns `null`");
  312. assert.strictEqual(_getRelatedTarget(badTarget2), null, "Element without `data-clipboard-target` returns `null`");
  313. });
  314. test("`_shouldPerformAsync` works", function(assert) {
  315. assert.expect(4);
  316. // Act & Assert
  317. assert.strictEqual(_shouldPerformAsync({ type: "beforecopy" }), false, "`beforecopy` should be performed synchronously");
  318. assert.strictEqual(_shouldPerformAsync({ type: "copy" }), false, "`copy` should be performed synchronously");
  319. assert.strictEqual(_shouldPerformAsync({ type: "destroy" }), false, "`destroy` should be performed synchronously");
  320. assert.strictEqual(_shouldPerformAsync({ type: "ready" }), true, "All other event types should be performed asynchronously");
  321. });
  322. test("`_dispatchCallback` can fire asynchronously", function(assert) {
  323. assert.expect(6);
  324. // Arrange
  325. var syncExec = false;
  326. var syncProof = false;
  327. var syncProveIt = function() {
  328. syncProof = true;
  329. };
  330. var asyncExec = true;
  331. var asyncProof = false;
  332. var asyncProveIt = function() {
  333. // Resume test evaluation
  334. QUnit.start();
  335. assert.strictEqual(asyncProof, false);
  336. asyncProof = true;
  337. assert.strictEqual(asyncProof, true);
  338. };
  339. // Act & Assert
  340. // Synchronous
  341. assert.strictEqual(syncProof, false);
  342. _dispatchCallback(syncProveIt, null, null, syncExec);
  343. assert.strictEqual(syncProof, true);
  344. // Asynchronous
  345. assert.strictEqual(asyncProof, false);
  346. _dispatchCallback(asyncProveIt, null, null, asyncExec);
  347. assert.strictEqual(asyncProof, false);
  348. // Stop test evaluation
  349. QUnit.stop();
  350. });
  351. module("core/private.js unit tests - flash", {
  352. setup: function() {
  353. flashState = _flashState;
  354. mimeType = window.navigator.mimeTypes["application/x-shockwave-flash"];
  355. ax = window.ActiveXObject;
  356. },
  357. teardown: function() {
  358. window.navigator.mimeTypes["application/x-shockwave-flash"] = mimeType;
  359. window.ActiveXObject = ax;
  360. _flashState = flashState;
  361. }
  362. });
  363. test("Detecting no Flash", function(assert) {
  364. assert.expect(1);
  365. // Arrange
  366. window.navigator.mimeTypes["application/x-shockwave-flash"] = undefined;
  367. window.ActiveXObject = undefined;
  368. // Act
  369. _detectFlashSupport(window.ActiveXObject);
  370. // Assert
  371. assert.strictEqual(_flashState.disabled, true);
  372. });
  373. test("Detecting has Flash mimetype", function(assert) {
  374. assert.expect(1);
  375. // Arrange
  376. window.navigator.mimeTypes["application/x-shockwave-flash"] = {};
  377. window.ActiveXObject = function() { };
  378. // Act
  379. _detectFlashSupport(window.ActiveXObject);
  380. // Assert
  381. assert.strictEqual(_flashState.disabled, false);
  382. });
  383. })(QUnit.module, QUnit.test);