uri_test.js 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174
  1. // Copyright 2006 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview Unit tests for goog.Uri.
  16. *
  17. * @author msamuel@google.com (Mike Samuel)
  18. */
  19. goog.provide('goog.UriTest');
  20. goog.require('goog.Uri');
  21. goog.require('goog.testing.jsunit');
  22. goog.setTestOnly('goog.UriTest');
  23. function testUriParse() {
  24. var uri = new goog.Uri('http://www.google.com:80/path?q=query#fragmento');
  25. assertEquals('http', uri.getScheme());
  26. assertEquals('', uri.getUserInfo());
  27. assertEquals('www.google.com', uri.getDomain());
  28. assertEquals(80, uri.getPort());
  29. assertEquals('/path', uri.getPath());
  30. assertEquals('q=query', uri.getQuery());
  31. assertEquals('fragmento', uri.getFragment());
  32. assertEquals(
  33. 'terer258+foo@gmail.com',
  34. goog.Uri.parse('mailto:terer258+foo@gmail.com').getPath());
  35. }
  36. function testUriParseWithNewline() {
  37. var uri = new goog.Uri('http://www.google.com:80/path?q=query#frag\nmento');
  38. assertEquals('http', uri.getScheme());
  39. assertEquals('', uri.getUserInfo());
  40. assertEquals('www.google.com', uri.getDomain());
  41. assertEquals(80, uri.getPort());
  42. assertEquals('/path', uri.getPath());
  43. assertEquals('q=query', uri.getQuery());
  44. assertEquals('frag\nmento', uri.getFragment());
  45. }
  46. function testUriParseAcceptsThingsWithToString() {
  47. // Ensure that the goog.Uri constructor coerces random types to strings.
  48. var uriStr = 'http://www.google.com:80/path?q=query#fragmento';
  49. var uri = new goog.Uri({toString: function() { return uriStr; }});
  50. assertEquals(
  51. 'http://www.google.com:80/path?q=query#fragmento', uri.toString());
  52. }
  53. function testUriCreate() {
  54. assertEquals(
  55. 'http://www.google.com:81/search%20path?q=what%20to%20eat%2Bdrink%3F',
  56. goog.Uri
  57. .create(
  58. 'http', null, 'www.google.com', 81, '/search path',
  59. (new goog.Uri.QueryData).set('q', 'what to eat+drink?'), null)
  60. .toString());
  61. assertEquals(
  62. 'http://www.google.com:80/search%20path?q=what%20to%20eat%2Bdrink%3F',
  63. goog.Uri
  64. .create(
  65. 'http', null, 'www.google.com', 80, '/search path',
  66. (new goog.Uri.QueryData).set('q', 'what to eat+drink?'), null)
  67. .toString());
  68. assertEquals(
  69. 'http://www.google.com/search%20path?q=what%20to%20eat%2Bdrink%3F',
  70. goog.Uri
  71. .create(
  72. 'http', null, 'www.google.com', null, '/search path',
  73. (new goog.Uri.QueryData).set('q', 'what to eat+drink?'), null)
  74. .toString());
  75. var createdUri = goog.Uri.create(
  76. 'http', null, 'www.google.com', null, '/search path',
  77. new goog.Uri.QueryData(null, null, true).set('Q', 'what to eat+drink?'),
  78. null);
  79. assertEquals(
  80. 'http://www.google.com/search%20path?q=what%20to%20eat%2Bdrink%3F',
  81. createdUri.toString());
  82. }
  83. function testClone() {
  84. var uri1 =
  85. new goog.Uri('http://user:pass@www.google.com:8080/foo?a=1&b=2#c=3');
  86. // getCount forces instantiation of internal data structures to more
  87. // thoroughly test clone.
  88. uri1.getQueryData().getCount();
  89. var uri2 = uri1.clone();
  90. assertNotEquals(uri1, uri2);
  91. assertEquals(uri1.toString(), uri2.toString());
  92. assertEquals(2, uri2.getQueryData().getCount());
  93. uri2.setParameterValues('q', 'bar');
  94. assertFalse(uri1.getParameterValue('q') == 'bar');
  95. }
  96. function testRelativeUris() {
  97. assertFalse(new goog.Uri('?hello').hasPath());
  98. }
  99. function testAbsolutePathResolution() {
  100. var uri1 = new goog.Uri('http://www.google.com:8080/path?q=query#fragmento');
  101. assertEquals(
  102. 'http://www.google.com:8080/foo',
  103. uri1.resolve(new goog.Uri('/foo')).toString());
  104. assertEquals(
  105. 'http://www.google.com:8080/foo/bar',
  106. goog.Uri.resolve('http://www.google.com:8080/search/', '/foo/bar')
  107. .toString());
  108. assertEquals(
  109. 'http://www.google.com:8080/path?q=que%2Br%20y#fragmento',
  110. goog.Uri
  111. .resolve(
  112. 'http://www.google.com:8080/', '/path?q=que%2Br%20y#fragmento')
  113. .toString());
  114. }
  115. function testRelativePathResolution() {
  116. var uri1 = new goog.Uri('http://www.google.com:8080/path?q=query#fragmento');
  117. assertEquals(
  118. 'http://www.google.com:8080/foo',
  119. uri1.resolve(goog.Uri.parse('foo')).toString());
  120. var uri2 = new goog.Uri('http://www.google.com:8080/search');
  121. assertEquals(
  122. 'http://www.google.com:8080/foo/bar',
  123. uri2.resolve(new goog.Uri('foo/bar')).toString());
  124. var uri3 = new goog.Uri('http://www.google.com:8080/search/');
  125. assertEquals(
  126. 'http://www.google.com:8080/search/foo/bar',
  127. uri3.resolve(new goog.Uri('foo/bar')).toString());
  128. var uri4 = new goog.Uri('foo');
  129. assertEquals('bar', uri4.resolve(new goog.Uri('bar')).toString());
  130. assertEquals(
  131. 'http://www.google.com:8080/search/..%2ffoo/bar',
  132. uri3.resolve(new goog.Uri('..%2ffoo/bar')).toString());
  133. }
  134. function testDomainResolution() {
  135. assertEquals(
  136. 'https://www.google.com/foo/bar',
  137. new goog.Uri('https://www.fark.com:443/search/')
  138. .resolve(new goog.Uri('//www.google.com/foo/bar'))
  139. .toString());
  140. assertEquals(
  141. 'http://www.google.com/',
  142. goog.Uri.resolve('http://www.fark.com/search/', '//www.google.com/')
  143. .toString());
  144. }
  145. function testQueryResolution() {
  146. assertEquals(
  147. 'http://www.google.com/search?q=new%20search',
  148. goog.Uri.parse('http://www.google.com/search?q=old+search')
  149. .resolve(goog.Uri.parse('?q=new%20search'))
  150. .toString());
  151. assertEquals(
  152. 'http://www.google.com/search?q=new%20search',
  153. goog.Uri.parse('http://www.google.com/search?q=old+search#hi')
  154. .resolve(goog.Uri.parse('?q=new%20search'))
  155. .toString());
  156. }
  157. function testFragmentResolution() {
  158. assertEquals(
  159. 'http://www.google.com/foo/bar?q=hi#there',
  160. goog.Uri.resolve('http://www.google.com/foo/bar?q=hi', '#there')
  161. .toString());
  162. assertEquals(
  163. 'http://www.google.com/foo/bar?q=hi#there',
  164. goog.Uri.resolve('http://www.google.com/foo/bar?q=hi#you', '#there')
  165. .toString());
  166. }
  167. function testBogusResolution() {
  168. var uri = goog.Uri.parse('some:base/url')
  169. .resolve(goog.Uri.parse('a://completely.different/url'));
  170. assertEquals('a://completely.different/url', uri.toString());
  171. }
  172. function testDotSegmentsRemovalRemoveLeadingDots() {
  173. // Test removing leading "../" and "./"
  174. assertEquals('bar', goog.Uri.removeDotSegments('../bar'));
  175. assertEquals('bar', goog.Uri.removeDotSegments('./bar'));
  176. assertEquals('bar', goog.Uri.removeDotSegments('.././bar'));
  177. assertEquals('bar', goog.Uri.removeDotSegments('.././bar'));
  178. }
  179. function testDotSegmentRemovalRemoveSingleDot() {
  180. // Tests replacing "/./" with "/"
  181. assertEquals('/foo/bar', goog.Uri.removeDotSegments('/foo/./bar'));
  182. assertEquals('/bar/', goog.Uri.removeDotSegments('/bar/./'));
  183. // Test replacing trailing "/." with "/"
  184. assertEquals('/', goog.Uri.removeDotSegments('/.'));
  185. assertEquals('/bar/', goog.Uri.removeDotSegments('/bar/.'));
  186. }
  187. function testDotSegmentRemovalRemoveDoubleDot() {
  188. // Test resolving "/../"
  189. assertEquals('/bar', goog.Uri.removeDotSegments('/foo/../bar'));
  190. assertEquals('/', goog.Uri.removeDotSegments('/bar/../'));
  191. // Test resolving trailing "/.."
  192. assertEquals('/', goog.Uri.removeDotSegments('/..'));
  193. assertEquals('/', goog.Uri.removeDotSegments('/bar/..'));
  194. assertEquals('/foo/', goog.Uri.removeDotSegments('/foo/bar/..'));
  195. }
  196. function testDotSegmentRemovalRemovePlainDots() {
  197. // RFC 3986, section 5.2.4, point 2.D.
  198. // Test resolving plain ".." or "."
  199. assertEquals('', goog.Uri.removeDotSegments('.'));
  200. assertEquals('', goog.Uri.removeDotSegments('..'));
  201. }
  202. function testPathConcatenation() {
  203. // Check accordenance with RFC 3986, section 5.2.4
  204. assertResolvedEquals('bar', '', 'bar');
  205. assertResolvedEquals('/bar', '/', 'bar');
  206. assertResolvedEquals('/bar', '/foo', '/bar');
  207. assertResolvedEquals('/foo/foo', '/foo/bar', 'foo');
  208. }
  209. function testPathConcatenationDontRemoveForEmptyUri() {
  210. // Resolving URIs with empty path should not result in dot segments removal.
  211. // See: algorithm in section 5.2.2: code inside 'if (R.path == "")' clause.
  212. assertResolvedEquals('/search/../foo', '/search/../foo', '');
  213. assertResolvedEquals('/search/./foo', '/search/./foo', '');
  214. }
  215. function testParameterGetters() {
  216. function assertArraysEqual(l1, l2) {
  217. if (!l1 || !l2) {
  218. assertEquals(l1, l2);
  219. return;
  220. }
  221. var l1s = l1.toString(), l2s = l2.toString();
  222. assertEquals(l1s, l2s);
  223. assertEquals(l1s, l1.length, l2.length);
  224. for (var i = 0; i < l1.length; ++i) {
  225. assertEquals(
  226. 'part ' + i + ' of ' + l1.length + ' in ' + l1s, l1[i], l2[i]);
  227. }
  228. }
  229. assertArraysEqual(
  230. ['v1', 'v2'],
  231. goog.Uri.parse('/path?a=b&key=v1&c=d&key=v2&keywithsuffix=v3')
  232. .getParameterValues('key'));
  233. assertArraysEqual(
  234. ['v1', 'v2'],
  235. goog.Uri.parse('/path?a=b&keY=v1&c=d&KEy=v2&keywithsuffix=v3', true)
  236. .getParameterValues('kEy'));
  237. assertEquals(
  238. 'v1', goog.Uri.parse('/path?key=v1&c=d&keywithsuffix=v3&key=v2')
  239. .getParameterValue('key'));
  240. assertEquals(
  241. 'v1', goog.Uri.parse('/path?kEY=v1&c=d&keywithsuffix=v3&key=v2', true)
  242. .getParameterValue('Key'));
  243. assertEquals(
  244. 'v1=v2',
  245. goog.Uri.parse('/path?key=v1=v2', true).getParameterValue('key'));
  246. assertEquals(
  247. 'v1=v2=v3',
  248. goog.Uri.parse('/path?key=v1=v2=v3', true).getParameterValue('key'));
  249. assertArraysEqual(
  250. undefined, goog.Uri.parse('/path?key=v1&c=d&keywithsuffix=v3&key=v2')
  251. .getParameterValue('nosuchkey'));
  252. // test boundary conditions
  253. assertArraysEqual(
  254. ['v1', 'v2'], goog.Uri.parse('/path?key=v1&c=d&key=v2&keywithsuffix=v3')
  255. .getParameterValues('key'));
  256. assertArraysEqual(
  257. ['v1', 'v2'], goog.Uri.parse('/path?key=v1&c=d&keywithsuffix=v3&key=v2')
  258. .getParameterValues('key'));
  259. // test no =
  260. assertArraysEqual(
  261. [''], goog.Uri.parse('/path?key').getParameterValues('key'));
  262. assertArraysEqual(
  263. [''], goog.Uri.parse('/path?key', true).getParameterValues('key'));
  264. assertArraysEqual(
  265. [''], goog.Uri.parse('/path?foo=bar&key').getParameterValues('key'));
  266. assertArraysEqual(
  267. [''],
  268. goog.Uri.parse('/path?foo=bar&key', true).getParameterValues('key'));
  269. assertEquals('', goog.Uri.parse('/path?key').getParameterValue('key'));
  270. assertEquals('', goog.Uri.parse('/path?key', true).getParameterValue('key'));
  271. assertEquals(
  272. '', goog.Uri.parse('/path?foo=bar&key').getParameterValue('key'));
  273. assertEquals(
  274. '', goog.Uri.parse('/path?foo=bar&key', true).getParameterValue('key'));
  275. var u = new goog.Uri('/path?a=b&key=v1&c=d&key=v2&keywithsuffix=v3');
  276. assertArraysEqual(u.getParameterValues('a'), ['b']);
  277. assertArraysEqual(u.getParameterValues('key'), ['v1', 'v2']);
  278. assertArraysEqual(u.getParameterValues('c'), ['d']);
  279. assertArraysEqual(u.getParameterValues('keywithsuffix'), ['v3']);
  280. assertArraysEqual(u.getParameterValues('KeyWITHSuffix'), []);
  281. // Make sure constructing from another URI preserves case-sensitivity
  282. var u2 = new goog.Uri(u);
  283. assertArraysEqual(u2.getParameterValues('a'), ['b']);
  284. assertArraysEqual(u2.getParameterValues('key'), ['v1', 'v2']);
  285. assertArraysEqual(u2.getParameterValues('c'), ['d']);
  286. assertArraysEqual(u2.getParameterValues('keywithsuffix'), ['v3']);
  287. assertArraysEqual(u2.getParameterValues('KeyWITHSuffix'), []);
  288. u = new goog.Uri('/path?a=b&key=v1&c=d&kEy=v2&keywithsuffix=v3', true);
  289. assertArraysEqual(u.getParameterValues('A'), ['b']);
  290. assertArraysEqual(u.getParameterValues('keY'), ['v1', 'v2']);
  291. assertArraysEqual(u.getParameterValues('c'), ['d']);
  292. assertArraysEqual(u.getParameterValues('keyWITHsuffix'), ['v3']);
  293. // Make sure constructing from another URI preserves case-insensitivity
  294. u2 = new goog.Uri(u);
  295. assertArraysEqual(u2.getParameterValues('A'), ['b']);
  296. assertArraysEqual(u2.getParameterValues('keY'), ['v1', 'v2']);
  297. assertArraysEqual(u2.getParameterValues('c'), ['d']);
  298. assertArraysEqual(u2.getParameterValues('keyWITHsuffix'), ['v3']);
  299. }
  300. function testRemoveParameter() {
  301. assertEquals(
  302. '/path?a=b&c=d&keywithsuffix=v3',
  303. goog.Uri.parse('/path?a=b&key=v1&c=d&key=v2&keywithsuffix=v3')
  304. .removeParameter('key')
  305. .toString());
  306. }
  307. function testParameterSetters() {
  308. assertEquals(
  309. '/path?a=b&key=newval&c=d&keywithsuffix=v3',
  310. goog.Uri.parse('/path?a=b&key=v1&c=d&key=v2&keywithsuffix=v3')
  311. .setParameterValue('key', 'newval')
  312. .toString());
  313. assertEquals(
  314. '/path?a=b&key=1&key=2&key=3&c=d&keywithsuffix=v3',
  315. goog.Uri.parse('/path?a=b&key=v1&c=d&key=v2&keywithsuffix=v3')
  316. .setParameterValues('key', ['1', '2', '3'])
  317. .toString());
  318. assertEquals(
  319. '/path', goog.Uri.parse('/path?key=v1&key=v2')
  320. .setParameterValues('key', [])
  321. .toString());
  322. // Test case-insensitive setters
  323. assertEquals(
  324. '/path?a=b&key=newval&c=d&keywithsuffix=v3',
  325. goog.Uri.parse('/path?a=b&key=v1&c=d&key=v2&keywithsuffix=v3', true)
  326. .setParameterValue('KEY', 'newval')
  327. .toString());
  328. assertEquals(
  329. '/path?a=b&key=1&key=2&key=3&c=d&keywithsuffix=v3',
  330. goog.Uri.parse('/path?a=b&key=v1&c=d&key=v2&keywithsuffix=v3', true)
  331. .setParameterValues('kEY', ['1', '2', '3'])
  332. .toString());
  333. }
  334. function testEncoding() {
  335. assertEquals('/foo bar baz', goog.Uri.parse('/foo%20bar%20baz').getPath());
  336. assertEquals('/foo+bar+baz', goog.Uri.parse('/foo+bar+baz').getPath());
  337. }
  338. function testSetScheme() {
  339. var uri = new goog.Uri('http://www.google.com:80/path?q=query#fragmento');
  340. uri.setScheme('https');
  341. assertTrue(uri.hasScheme());
  342. assertEquals('https', uri.getScheme());
  343. assertEquals(
  344. 'https://www.google.com:80/path?q=query#fragmento', uri.toString());
  345. uri.setScheme(encodeURIComponent('ab cd'), true);
  346. assertTrue(uri.hasScheme());
  347. assertEquals('ab cd', uri.getScheme());
  348. assertEquals(
  349. 'ab%20cd://www.google.com:80/path?q=query#fragmento', uri.toString());
  350. uri.setScheme('http:');
  351. assertTrue(uri.hasScheme());
  352. assertEquals('http', uri.getScheme());
  353. assertEquals(
  354. 'http://www.google.com:80/path?q=query#fragmento', uri.toString());
  355. uri.setScheme('');
  356. assertFalse(uri.hasScheme());
  357. assertEquals('', uri.getScheme());
  358. assertEquals('//www.google.com:80/path?q=query#fragmento', uri.toString());
  359. }
  360. function testSetDomain() {
  361. var uri = new goog.Uri('http://www.google.com:80/path?q=query#fragmento');
  362. uri.setDomain('\u1e21oogle.com');
  363. assertTrue(uri.hasDomain());
  364. assertEquals('\u1e21oogle.com', uri.getDomain());
  365. assertEquals(
  366. 'http://%E1%B8%A1oogle.com:80/path?q=query#fragmento', uri.toString());
  367. uri.setDomain(encodeURIComponent('\u1e21oogle.com'), true);
  368. assertTrue(uri.hasDomain());
  369. assertEquals('\u1e21oogle.com', uri.getDomain());
  370. assertEquals(
  371. 'http://%E1%B8%A1oogle.com:80/path?q=query#fragmento', uri.toString());
  372. uri.setDomain('');
  373. assertFalse(uri.hasDomain());
  374. assertEquals('', uri.getDomain());
  375. assertEquals('http:/path?q=query#fragmento', uri.toString());
  376. }
  377. function testSetPort() {
  378. var uri = new goog.Uri('http://www.google.com:80/path?q=query#fragmento');
  379. assertThrows(function() { uri.setPort(-1); });
  380. assertEquals(80, uri.getPort());
  381. assertThrows(function() { uri.setPort('a'); });
  382. assertEquals(80, uri.getPort());
  383. uri.setPort(443);
  384. assertTrue(uri.hasPort());
  385. assertEquals(443, uri.getPort());
  386. assertEquals(
  387. 'http://www.google.com:443/path?q=query#fragmento', uri.toString());
  388. // TODO(chrishenry): This is undocumented, but exist in previous unit
  389. // test. We should clarify whether this is intended (alternatively,
  390. // setPort(0) also works).
  391. uri.setPort(null);
  392. assertFalse(uri.hasPort());
  393. assertEquals(null, uri.getPort());
  394. assertEquals('http://www.google.com/path?q=query#fragmento', uri.toString());
  395. }
  396. function testSetPath() {
  397. var uri = new goog.Uri('http://www.google.com:80/path?q=query#fragmento');
  398. uri.setPath('/search path/');
  399. assertTrue(uri.hasPath());
  400. assertEquals('/search path/', uri.getPath());
  401. assertEquals(
  402. 'http://www.google.com:80/search%20path/?q=query#fragmento',
  403. uri.toString());
  404. uri.setPath(encodeURIComponent('search path 2/'), true);
  405. assertTrue(uri.hasPath());
  406. assertEquals('search path 2%2F', uri.getPath());
  407. assertEquals(
  408. 'http://www.google.com:80/search%20path%202%2F?q=query#fragmento',
  409. uri.toString());
  410. uri.setPath('');
  411. assertFalse(uri.hasPath());
  412. assertEquals('', uri.getPath());
  413. assertEquals('http://www.google.com:80?q=query#fragmento', uri.toString());
  414. }
  415. function testSetFragment() {
  416. var uri = new goog.Uri('http://www.google.com:80/path?q=query#fragmento');
  417. uri.setFragment('foo?bar=a b&baz=2');
  418. assertTrue(uri.hasFragment());
  419. assertEquals('foo?bar=a b&baz=2', uri.getFragment());
  420. assertEquals(
  421. 'http://www.google.com:80/path?q=query#foo?bar=a%20b&baz=2',
  422. uri.toString());
  423. uri.setFragment(encodeURIComponent('foo?bar=a b&baz=3'), true);
  424. assertTrue(uri.hasFragment());
  425. assertEquals('foo?bar=a b&baz=3', uri.getFragment());
  426. assertEquals(
  427. 'http://www.google.com:80/path?q=query#foo?bar=a%20b&baz=3',
  428. uri.toString());
  429. uri.setFragment('');
  430. assertFalse(uri.hasFragment());
  431. assertEquals('', uri.getFragment());
  432. assertEquals('http://www.google.com:80/path?q=query', uri.toString());
  433. }
  434. function testSetUserInfo() {
  435. var uri = new goog.Uri('http://www.google.com:80/path?q=query#fragmento');
  436. uri.setUserInfo('user:pw d');
  437. assertTrue(uri.hasUserInfo());
  438. assertEquals('user:pw d', uri.getUserInfo());
  439. assertEquals(
  440. 'http://user:pw%20d@www.google.com:80/path?q=query#fragmento',
  441. uri.toString());
  442. uri.setUserInfo(encodeURIComponent('user:pw d2'), true);
  443. assertTrue(uri.hasUserInfo());
  444. assertEquals('user:pw d2', uri.getUserInfo());
  445. assertEquals(
  446. 'http://user:pw%20d2@www.google.com:80/path?q=query#fragmento',
  447. uri.toString());
  448. uri.setUserInfo('user');
  449. assertTrue(uri.hasUserInfo());
  450. assertEquals('user', uri.getUserInfo());
  451. assertEquals(
  452. 'http://user@www.google.com:80/path?q=query#fragmento', uri.toString());
  453. uri.setUserInfo('');
  454. assertFalse(uri.hasUserInfo());
  455. assertEquals('', uri.getUserInfo());
  456. assertEquals(
  457. 'http://www.google.com:80/path?q=query#fragmento', uri.toString());
  458. }
  459. function testSetParameterValues() {
  460. var uri = new goog.Uri('http://www.google.com:80/path?q=query#fragmento');
  461. uri.setParameterValues('q', ['foo', 'other query']);
  462. assertEquals(
  463. 'http://www.google.com:80/path?q=foo&q=other%20query#fragmento',
  464. uri.toString());
  465. uri.setParameterValues('lang', 'en');
  466. assertEquals(
  467. 'http://www.google.com:80/path?q=foo&q=other%20query&lang=en#fragmento',
  468. uri.toString());
  469. }
  470. function testTreatmentOfAt1() {
  471. var uri = new goog.Uri('http://www.google.com?q=johndoe@gmail.com');
  472. assertEquals('http', uri.getScheme());
  473. assertEquals('www.google.com', uri.getDomain());
  474. assertEquals('johndoe@gmail.com', uri.getParameterValue('q'));
  475. uri = goog.Uri.create(
  476. 'http', null, 'www.google.com', null, null, 'q=johndoe@gmail.com', null);
  477. assertEquals('http://www.google.com?q=johndoe%40gmail.com', uri.toString());
  478. }
  479. function testTreatmentOfAt2() {
  480. var uri = new goog.Uri('http://test/~johndoe@gmail.com/foo');
  481. assertEquals('http', uri.getScheme());
  482. assertEquals('test', uri.getDomain());
  483. assertEquals('/~johndoe@gmail.com/foo', uri.getPath());
  484. assertEquals(
  485. 'http://test/~johndoe@gmail.com/foo',
  486. goog.Uri
  487. .create(
  488. 'http', null, 'test', null, '/~johndoe@gmail.com/foo', null, null)
  489. .toString());
  490. }
  491. function testTreatmentOfAt3() {
  492. var uri = new goog.Uri('ftp://skroob:1234@teleport/~skroob@vacuum');
  493. assertEquals('ftp', uri.getScheme());
  494. assertEquals('skroob:1234', uri.getUserInfo());
  495. assertEquals('teleport', uri.getDomain());
  496. assertEquals('/~skroob@vacuum', uri.getPath());
  497. assertEquals(
  498. 'ftp://skroob:1234@teleport/~skroob@vacuum',
  499. goog.Uri
  500. .create(
  501. 'ftp', 'skroob:1234', 'teleport', null, '/~skroob@vacuum', null,
  502. null)
  503. .toString());
  504. }
  505. function testTreatmentOfAt4() {
  506. assertEquals(
  507. 'ftp://darkhelmet:45%4078@teleport/~dhelmet@vacuum',
  508. goog.Uri
  509. .create(
  510. 'ftp', 'darkhelmet:45@78', 'teleport', null, '/~dhelmet@vacuum',
  511. null, null)
  512. .toString());
  513. }
  514. function testSameDomain1() {
  515. var uri1 = 'http://www.google.com/a';
  516. var uri2 = 'http://www.google.com/b';
  517. assertTrue(goog.Uri.haveSameDomain(uri1, uri2));
  518. assertTrue(goog.Uri.haveSameDomain(uri2, uri1));
  519. }
  520. function testSameDomain2() {
  521. var uri1 = 'http://www.google.com:1234/a';
  522. var uri2 = 'http://www.google.com/b';
  523. assertFalse(goog.Uri.haveSameDomain(uri1, uri2));
  524. assertFalse(goog.Uri.haveSameDomain(uri2, uri1));
  525. }
  526. function testSameDomain3() {
  527. var uri1 = 'www.google.com/a';
  528. var uri2 = 'http://www.google.com/b';
  529. assertFalse(goog.Uri.haveSameDomain(uri1, uri2));
  530. assertFalse(goog.Uri.haveSameDomain(uri2, uri1));
  531. }
  532. function testSameDomain4() {
  533. var uri1 = '/a';
  534. var uri2 = 'http://www.google.com/b';
  535. assertFalse(goog.Uri.haveSameDomain(uri1, uri2));
  536. assertFalse(goog.Uri.haveSameDomain(uri2, uri1));
  537. }
  538. function testSameDomain5() {
  539. var uri1 = 'http://www.google.com/a';
  540. var uri2 = 'http://mail.google.com/b';
  541. assertFalse(goog.Uri.haveSameDomain(uri1, uri2));
  542. assertFalse(goog.Uri.haveSameDomain(uri2, uri1));
  543. }
  544. function testSameDomain6() {
  545. var uri1 = '/a';
  546. var uri2 = '/b';
  547. assertTrue(goog.Uri.haveSameDomain(uri1, uri2));
  548. assertTrue(goog.Uri.haveSameDomain(uri2, uri1));
  549. }
  550. function testMakeUnique() {
  551. var uri1 = new goog.Uri('http://www.google.com/setgmail');
  552. uri1.makeUnique();
  553. var uri2 = new goog.Uri('http://www.google.com/setgmail');
  554. uri2.makeUnique();
  555. assertTrue(uri1.getQueryData().containsKey(goog.Uri.RANDOM_PARAM));
  556. assertTrue(uri1.toString() != uri2.toString());
  557. }
  558. function testSetReadOnly() {
  559. var uri = new goog.Uri('http://www.google.com/setgmail');
  560. uri.setReadOnly(true);
  561. assertThrows(function() { uri.setParameterValue('cant', 'dothis'); });
  562. }
  563. function testSetReadOnlyChained() {
  564. var uri = new goog.Uri('http://www.google.com/setgmail').setReadOnly(true);
  565. assertThrows(function() { uri.setParameterValue('cant', 'dothis'); });
  566. }
  567. function testQueryDataCount() {
  568. var qd = new goog.Uri.QueryData('a=A&b=B&a=A2&b=B2&c=C');
  569. assertEquals(5, qd.getCount());
  570. }
  571. function testQueryDataRemove() {
  572. var qd = new goog.Uri.QueryData('a=A&b=B&a=A2&b=B2&c=C');
  573. qd.remove('c');
  574. assertEquals(4, qd.getCount());
  575. assertEquals('a=A&a=A2&b=B&b=B2', String(qd));
  576. qd.remove('a');
  577. assertEquals(2, qd.getCount());
  578. assertEquals('b=B&b=B2', String(qd));
  579. }
  580. function testQueryDataClear() {
  581. var qd = new goog.Uri.QueryData('a=A&b=B&a=A2&b=B2&c=C');
  582. qd.clear();
  583. assertEquals(0, qd.getCount());
  584. assertEquals('', String(qd));
  585. }
  586. function testQueryDataIsEmpty() {
  587. var qd = new goog.Uri.QueryData('a=A&b=B&a=A2&b=B2&c=C');
  588. qd.remove('a');
  589. assertFalse(qd.isEmpty());
  590. qd.remove('b');
  591. assertFalse(qd.isEmpty());
  592. qd.remove('c');
  593. assertTrue(qd.isEmpty());
  594. qd = new goog.Uri.QueryData('a=A&b=B&a=A2&b=B2&c=C');
  595. qd.clear();
  596. assertTrue(qd.isEmpty());
  597. qd = new goog.Uri.QueryData('');
  598. assertTrue(qd.isEmpty());
  599. }
  600. function testQueryDataContainsKey() {
  601. var qd = new goog.Uri.QueryData('a=A&b=B&a=A2&b=B2&c=C');
  602. assertTrue(qd.containsKey('a'));
  603. assertTrue(qd.containsKey('b'));
  604. assertTrue(qd.containsKey('c'));
  605. qd.remove('a');
  606. assertFalse(qd.containsKey('a'));
  607. assertTrue(qd.containsKey('b'));
  608. assertTrue(qd.containsKey('c'));
  609. qd.remove('b');
  610. assertFalse(qd.containsKey('a'));
  611. assertFalse(qd.containsKey('b'));
  612. assertTrue(qd.containsKey('c'));
  613. qd.remove('c');
  614. assertFalse(qd.containsKey('a'));
  615. assertFalse(qd.containsKey('b'));
  616. assertFalse(qd.containsKey('c'));
  617. qd = new goog.Uri.QueryData('a=A&b=B&a=A2&b=B2&c=C');
  618. qd.clear();
  619. assertFalse(qd.containsKey('a'));
  620. assertFalse(qd.containsKey('b'));
  621. assertFalse(qd.containsKey('c'));
  622. // Test case-insensitive
  623. qd = new goog.Uri.QueryData('aaa=A&bbb=B&aaa=A2&bbbb=B2&ccc=C', null, true);
  624. assertTrue(qd.containsKey('aaa'));
  625. assertTrue(qd.containsKey('bBb'));
  626. assertTrue(qd.containsKey('CCC'));
  627. qd = new goog.Uri.QueryData('a=b=c');
  628. assertTrue(qd.containsKey('a'));
  629. assertFalse(qd.containsKey('b'));
  630. }
  631. function testQueryDataContainsValue() {
  632. var qd = new goog.Uri.QueryData('a=A&b=B&a=A2&b=B2&c=C');
  633. assertTrue(qd.containsValue('A'));
  634. assertTrue(qd.containsValue('B'));
  635. assertTrue(qd.containsValue('A2'));
  636. assertTrue(qd.containsValue('B2'));
  637. assertTrue(qd.containsValue('C'));
  638. qd.remove('a');
  639. assertFalse(qd.containsValue('A'));
  640. assertTrue(qd.containsValue('B'));
  641. assertFalse(qd.containsValue('A2'));
  642. assertTrue(qd.containsValue('B2'));
  643. assertTrue(qd.containsValue('C'));
  644. qd.remove('b');
  645. assertFalse(qd.containsValue('A'));
  646. assertFalse(qd.containsValue('B'));
  647. assertFalse(qd.containsValue('A2'));
  648. assertFalse(qd.containsValue('B2'));
  649. assertTrue(qd.containsValue('C'));
  650. qd.remove('c');
  651. assertFalse(qd.containsValue('A'));
  652. assertFalse(qd.containsValue('B'));
  653. assertFalse(qd.containsValue('A2'));
  654. assertFalse(qd.containsValue('B2'));
  655. assertFalse(qd.containsValue('C'));
  656. qd = new goog.Uri.QueryData('a=A&b=B&a=A2&b=B2&c=C');
  657. qd.clear();
  658. assertFalse(qd.containsValue('A'));
  659. assertFalse(qd.containsValue('B'));
  660. assertFalse(qd.containsValue('A2'));
  661. assertFalse(qd.containsValue('B2'));
  662. assertFalse(qd.containsValue('C'));
  663. qd = new goog.Uri.QueryData('a=b=c');
  664. assertTrue(qd.containsValue('b=c'));
  665. assertFalse(qd.containsValue('b'));
  666. assertFalse(qd.containsValue('c'));
  667. }
  668. function testQueryDataGetKeys() {
  669. var qd = new goog.Uri.QueryData('a=A&b=B&a=A2&b=B2&c=C=extra');
  670. assertEquals('aabbc', qd.getKeys().join(''));
  671. qd.remove('a');
  672. assertEquals('bbc', qd.getKeys().join(''));
  673. qd.add('d', 'D');
  674. qd.add('d', 'D');
  675. assertEquals('bbcdd', qd.getKeys().join(''));
  676. // Test case-insensitive
  677. qd = new goog.Uri.QueryData('A=A&B=B&a=A2&b=B2&C=C=extra', null, true);
  678. assertEquals('aabbc', qd.getKeys().join(''));
  679. qd.remove('a');
  680. assertEquals('bbc', qd.getKeys().join(''));
  681. qd.add('d', 'D');
  682. qd.add('D', 'D');
  683. assertEquals('bbcdd', qd.getKeys().join(''));
  684. }
  685. function testQueryDataForEach() {
  686. var qd = new goog.Uri.QueryData('a=A&b=B&a=A2&b=B2&c=C=extra');
  687. var calls = [];
  688. qd.forEach(function(value, key) {
  689. calls.push([value, key]);
  690. });
  691. assertArrayEquals(
  692. [
  693. // value, key
  694. ['A', 'a'], ['A2', 'a'], ['B', 'b'], ['B2', 'b'], ['C=extra', 'c']
  695. ],
  696. calls);
  697. }
  698. function testQueryDataGetValues() {
  699. var qd = new goog.Uri.QueryData('a=A&b=B&a=A2&b=B2&c=C=extra');
  700. assertArrayEquals(['A', 'A2', 'B', 'B2', 'C=extra'], qd.getValues());
  701. qd.remove('a');
  702. assertArrayEquals(['B', 'B2', 'C=extra'], qd.getValues());
  703. qd.add('d', 'D');
  704. qd.add('d', 'D');
  705. assertArrayEquals(['B', 'B2', 'C=extra', 'D', 'D'], qd.getValues());
  706. qd.add('e', new String('Eee'));
  707. assertArrayEquals(['B', 'B2', 'C=extra', 'D', 'D', 'Eee'], qd.getValues());
  708. assertArrayEquals(['Eee'], qd.getValues('e'));
  709. }
  710. function testQueryDataSet() {
  711. var qd = new goog.Uri.QueryData('a=A&b=B&a=A2&b=B2&c=C');
  712. qd.set('d', 'D');
  713. assertEquals('a=A&a=A2&b=B&b=B2&c=C&d=D', String(qd));
  714. qd.set('d', 'D2');
  715. assertEquals('a=A&a=A2&b=B&b=B2&c=C&d=D2', String(qd));
  716. qd.set('a', 'A3');
  717. assertEquals('a=A3&b=B&b=B2&c=C&d=D2', String(qd));
  718. qd.remove('a');
  719. qd.set('a', 'A4');
  720. // this is different in IE and Mozilla so we cannot use the toString to test
  721. assertEquals('A4', qd.get('a'));
  722. }
  723. function testQueryDataGet() {
  724. var qd = new goog.Uri.QueryData('a=A&b=B&a=A2&b=B2&c=C=extra');
  725. assertEquals('A', qd.get('a'));
  726. assertEquals('B', qd.get('b'));
  727. assertEquals('C=extra', qd.get('c'));
  728. assertEquals('Default', qd.get('d', 'Default'));
  729. qd = new goog.Uri.QueryData('a=A&b=B&a=A2&b=B2&c=C=extra', null, true);
  730. assertEquals('A', qd.get('A'));
  731. assertEquals('B', qd.get('b'));
  732. assertEquals('C=extra', qd.get('C'));
  733. assertEquals('Default', qd.get('D', 'Default'));
  734. // Some unit tests pass undefined to get method (even though the type
  735. // for key is {string}). This is not caught by JsCompiler as
  736. // tests aren't typically compiled.
  737. assertUndefined(qd.get(undefined));
  738. }
  739. function testQueryDataSetValues() {
  740. var qd = new goog.Uri.QueryData('a=A&b=B&a=A2&b=B2&c=C');
  741. qd.setValues('a', ['A3', 'A4', 'A5']);
  742. assertEquals('a=A3&a=A4&a=A5&b=B&b=B2&c=C', String(qd));
  743. qd.setValues('d', ['D']);
  744. assertEquals('a=A3&a=A4&a=A5&b=B&b=B2&c=C&d=D', String(qd));
  745. qd.setValues('e', []);
  746. assertEquals('a=A3&a=A4&a=A5&b=B&b=B2&c=C&d=D', String(qd));
  747. }
  748. function testQueryDataSetIgnoreCase() {
  749. var qd = new goog.Uri.QueryData('aaA=one&BBb=two&cCc=three');
  750. assertEquals('one', qd.get('aaA'));
  751. assertEquals(undefined, qd.get('aaa'));
  752. qd.setIgnoreCase(true);
  753. assertEquals('one', qd.get('aaA'));
  754. assertEquals('one', qd.get('aaa'));
  755. qd.setIgnoreCase(false);
  756. assertEquals(undefined, qd.get('aaA'));
  757. assertEquals('one', qd.get('aaa'));
  758. qd.add('DdD', 'four');
  759. assertEquals('four', qd.get('DdD'));
  760. assertEquals(undefined, qd.get('ddd'));
  761. }
  762. function testQueryDataSetIgnoreCaseWithMultipleValues() {
  763. var qd = new goog.Uri.QueryData('aaA=one&aaA=two');
  764. qd.setIgnoreCase(true);
  765. assertArrayEquals(['one', 'two'], qd.getValues('aaA'));
  766. assertArrayEquals(['one', 'two'], qd.getValues('aaa'));
  767. }
  768. function testQueryDataExtend() {
  769. var qd1 = new goog.Uri.QueryData('a=A&b=B&c=C');
  770. var qd2 = new goog.Uri.QueryData('d=D&e=E');
  771. qd1.extend(qd2);
  772. assertEquals('a=A&b=B&c=C&d=D&e=E', String(qd1));
  773. qd1 = new goog.Uri.QueryData('a=A&b=B&c=C');
  774. qd2 = new goog.Uri.QueryData('d=D&e=E');
  775. var qd3 = new goog.Uri.QueryData('f=F&g=G');
  776. qd1.extend(qd2, qd3);
  777. assertEquals('a=A&b=B&c=C&d=D&e=E&f=F&g=G', String(qd1));
  778. qd1 = new goog.Uri.QueryData('a=A&b=B&c=C');
  779. qd2 = new goog.Uri.QueryData('a=A&c=C');
  780. qd1.extend(qd2);
  781. assertEquals('a=A&a=A&b=B&c=C&c=C', String(qd1));
  782. }
  783. function testQueryDataCreateFromMap() {
  784. assertEquals('', String(goog.Uri.QueryData.createFromMap({})));
  785. assertEquals(
  786. 'a=A&b=B&c=C',
  787. String(goog.Uri.QueryData.createFromMap({a: 'A', b: 'B', c: 'C'})));
  788. assertEquals(
  789. 'a=foo%26bar', String(goog.Uri.QueryData.createFromMap({a: 'foo&bar'})));
  790. }
  791. function testQueryDataCreateFromMapWithArrayValues() {
  792. var obj = {'key': ['1', '2', '3']};
  793. var qd = goog.Uri.QueryData.createFromMap(obj);
  794. assertEquals('key=1&key=2&key=3', qd.toString());
  795. qd.add('breakCache', 1);
  796. obj.key.push('4');
  797. assertEquals('key=1&key=2&key=3&breakCache=1', qd.toString());
  798. }
  799. function testQueryDataCreateFromKeysValues() {
  800. assertEquals('', String(goog.Uri.QueryData.createFromKeysValues([], [])));
  801. assertEquals(
  802. 'a=A&b=B&c=C', String(
  803. goog.Uri.QueryData.createFromKeysValues(
  804. ['a', 'b', 'c'], ['A', 'B', 'C'])));
  805. assertEquals(
  806. 'a=A&a=B&a=C', String(
  807. goog.Uri.QueryData.createFromKeysValues(
  808. ['a', 'a', 'a'], ['A', 'B', 'C'])));
  809. }
  810. function testQueryDataAddMultipleValuesWithSameKey() {
  811. var qd = new goog.Uri.QueryData();
  812. qd.add('abc', 'v');
  813. qd.add('abc', 'v2');
  814. qd.add('abc', 'v3');
  815. assertEquals('abc=v&abc=v2&abc=v3', qd.toString());
  816. }
  817. function testQueryDataAddWithArray() {
  818. var qd = new goog.Uri.QueryData();
  819. qd.add('abc', ['v', 'v2']);
  820. assertEquals('abc=v%2Cv2', qd.toString());
  821. }
  822. function testFragmentEncoding() {
  823. var allowedInFragment = /[A-Za-z0-9\-._~!$&'()*+,;=:@/?]/g;
  824. var sb = [];
  825. for (var i = 33; i < 500; i++) { // arbitrarily use first 500 chars.
  826. sb.push(String.fromCharCode(i));
  827. }
  828. var testString = sb.join('');
  829. var fragment = new goog.Uri().setFragment(testString).toString();
  830. // Remove first '#' character.
  831. fragment = fragment.substr(1);
  832. // Strip all percent encoded characters, as they're ok.
  833. fragment = fragment.replace(/%[0-9A-F][0-9A-F]/g, '');
  834. // Remove allowed characters.
  835. fragment = fragment.replace(allowedInFragment, '');
  836. // Only illegal characters should remain, which is a fail.
  837. assertEquals('String should be empty', 0, fragment.length);
  838. }
  839. function testStrictDoubleEncodingRemoval() {
  840. var url = goog.Uri.parse('dummy/a%25invalid');
  841. assertEquals('dummy/a%25invalid', url.toString());
  842. url = goog.Uri.parse('dummy/a%252fdouble-encoded-slash');
  843. assertEquals('dummy/a%252fdouble-encoded-slash', url.toString());
  844. url = goog.Uri.parse('https://example.com/a%25%2f%25bcd%25%25');
  845. assertEquals('https://example.com/a%25%2f%25bcd%25%25', url.toString());
  846. }
  847. // Tests, that creating URI from components and then
  848. // getting the components back yields equal results.
  849. // The special attention is paid to test proper encoding
  850. // and decoding of URI components.
  851. function testComponentsAfterUriCreate() {
  852. var createdUri = new goog.Uri.create(
  853. '%40', // scheme
  854. '%41', // user info
  855. '%42', // domain
  856. 43, // port
  857. '%44', // path
  858. '%45', // query
  859. '%46'); // fragment
  860. assertEquals('%40', createdUri.getScheme());
  861. assertEquals('%41', createdUri.getUserInfo());
  862. assertEquals('%42', createdUri.getDomain());
  863. assertEquals(43, createdUri.getPort());
  864. assertEquals('%44', createdUri.getPath());
  865. assertEquals('%2545', createdUri.getQuery()); // returns encoded value
  866. assertEquals('%45', createdUri.getDecodedQuery());
  867. assertEquals('%2545', createdUri.getEncodedQuery());
  868. assertEquals('%46', createdUri.getFragment());
  869. }
  870. // Tests setting the query string and then reading back
  871. // query parameter values.
  872. function testSetQueryAndGetParameterValue() {
  873. var uri = new goog.Uri();
  874. // Sets query as decoded string.
  875. uri.setQuery('i=j&k');
  876. assertEquals('?i=j&k', uri.toString());
  877. assertEquals('i=j&k', uri.getDecodedQuery());
  878. assertEquals('i=j&k', uri.getEncodedQuery());
  879. assertEquals('i=j&k', uri.getQuery()); // returns encoded value
  880. assertEquals('j', uri.getParameterValue('i'));
  881. assertEquals('', uri.getParameterValue('k'));
  882. // Sets query as encoded string.
  883. uri.setQuery('i=j&k', true);
  884. assertEquals('?i=j&k', uri.toString());
  885. assertEquals('i=j&k', uri.getDecodedQuery());
  886. assertEquals('i=j&k', uri.getEncodedQuery());
  887. assertEquals('i=j&k', uri.getQuery()); // returns encoded value
  888. assertEquals('j', uri.getParameterValue('i'));
  889. assertEquals('', uri.getParameterValue('k'));
  890. // Sets query as decoded string.
  891. uri.setQuery('i=j%26k');
  892. assertEquals('?i=j%2526k', uri.toString());
  893. assertEquals('i=j%26k', uri.getDecodedQuery());
  894. assertEquals('i=j%2526k', uri.getEncodedQuery());
  895. assertEquals('i=j%2526k', uri.getQuery()); // returns encoded value
  896. assertEquals('j%26k', uri.getParameterValue('i'));
  897. assertUndefined(uri.getParameterValue('k'));
  898. // Sets query as encoded string.
  899. uri.setQuery('i=j%26k', true);
  900. assertEquals('?i=j%26k', uri.toString());
  901. assertEquals('i=j&k', uri.getDecodedQuery());
  902. assertEquals('i=j%26k', uri.getEncodedQuery());
  903. assertEquals('i=j%26k', uri.getQuery()); // returns encoded value
  904. assertEquals('j&k', uri.getParameterValue('i'));
  905. assertUndefined(uri.getParameterValue('k'));
  906. }
  907. // Tests setting query parameter values and the reading back the query string.
  908. function testSetParameterValueAndGetQuery() {
  909. var uri = new goog.Uri();
  910. uri.setParameterValue('a', 'b&c');
  911. assertEquals('?a=b%26c', uri.toString());
  912. assertEquals('a=b&c', uri.getDecodedQuery());
  913. assertEquals('a=b%26c', uri.getEncodedQuery());
  914. assertEquals('a=b%26c', uri.getQuery()); // returns encoded value
  915. uri.setParameterValue('a', 'b%26c');
  916. assertEquals('?a=b%2526c', uri.toString());
  917. assertEquals('a=b%26c', uri.getDecodedQuery());
  918. assertEquals('a=b%2526c', uri.getEncodedQuery());
  919. assertEquals('a=b%2526c', uri.getQuery()); // returns encoded value
  920. }
  921. // Tests that building a URI with a query string and then reading it back
  922. // gives the same result.
  923. function testQueryNotModified() {
  924. assertEquals('?foo', new goog.Uri('?foo').toString());
  925. assertEquals('?foo=', new goog.Uri('?foo=').toString());
  926. assertEquals('?foo=bar', new goog.Uri('?foo=bar').toString());
  927. assertEquals('?&=&=&', new goog.Uri('?&=&=&').toString());
  928. }
  929. function testRelativePathEscapesColon() {
  930. assertEquals(
  931. 'javascript%3aalert(1)',
  932. new goog.Uri().setPath('javascript:alert(1)').toString());
  933. }
  934. function testAbsolutePathDoesNotEscapeColon() {
  935. assertEquals(
  936. '/javascript:alert(1)', new goog.Uri('/javascript:alert(1)').toString());
  937. }
  938. function testColonInPathNotUnescaped() {
  939. assertEquals(
  940. '/javascript%3aalert(1)',
  941. new goog.Uri('/javascript%3aalert(1)').toString());
  942. assertEquals(
  943. 'javascript%3aalert(1)',
  944. new goog.Uri('javascript%3aalert(1)').toString());
  945. assertEquals(
  946. 'javascript:alert(1)', new goog.Uri('javascript:alert(1)').toString());
  947. assertEquals(
  948. 'http://www.foo.bar/path:with:colon/x',
  949. new goog.Uri('http://www.foo.bar/path:with:colon/x').toString());
  950. assertEquals(
  951. '//www.foo.bar/path:with:colon/x',
  952. new goog.Uri('//www.foo.bar/path:with:colon/x').toString());
  953. }
  954. // verifies bug http://b/9821952
  955. function testGetQueryForEmptyString() {
  956. var queryData = new goog.Uri.QueryData('a=b&c=d');
  957. assertArrayEquals(['b', 'd'], queryData.getValues());
  958. assertArrayEquals([], queryData.getValues(''));
  959. queryData = new goog.Uri.QueryData('a=b&c=d&=e');
  960. assertArrayEquals(['e'], queryData.getValues(''));
  961. }
  962. function testRestrictedCharactersArePreserved() {
  963. var uri = new goog.Uri(
  964. 'ht%74p://hos%74.example.%2f.com/pa%74h%2f-with-embedded-slash/');
  965. assertEquals('http', uri.getScheme());
  966. assertEquals('host.example.%2f.com', uri.getDomain());
  967. assertEquals('/path%2f-with-embedded-slash/', uri.getPath());
  968. assertEquals(
  969. 'http://host.example.%2f.com/path%2f-with-embedded-slash/',
  970. uri.toString());
  971. }
  972. function testFileUriWithNoDomainToString() {
  973. // Regression test for https://github.com/google/closure-library/issues/104.
  974. var uri = new goog.Uri('file:///a/b');
  975. assertEquals('file:///a/b', uri.toString());
  976. }
  977. function assertDotRemovedEquals(expected, path) {
  978. assertEquals(expected, goog.Uri.removeDotSegments(path));
  979. }
  980. function assertResolvedEquals(expected, base, other) {
  981. assertEquals(expected, goog.Uri.resolve(base, other).toString());
  982. }