b2026c1b56143963780938cb64a2fea2bb2524e1
1 QUnit
.module( 'mediawiki.Uri', QUnit
.newMwEnvironment({
3 this.mwUriOrg
= mw
.Uri
;
4 mw
.Uri
= mw
.UriRelative( 'http://example.org/w/index.php' );
6 teardown: function () {
7 mw
.Uri
= this.mwUriOrg
;
12 $.each( [true, false], function ( i
, strictMode
) {
13 QUnit
.test( 'Basic mw.Uri object test in ' + ( strictMode
? '' : 'non-' ) + 'strict mode for a simple HTTP URI', 2, function ( assert
) {
15 uriString
= 'http://www.ietf.org/rfc/rfc2396.txt';
16 uri
= new mw
.Uri( uriString
, {
17 strictMode
: strictMode
22 protocol
: uri
.protocol
,
27 fragment
: uri
.fragment
32 path
: '/rfc/rfc2396.txt',
36 'basic object properties'
41 userInfo
: uri
.getUserInfo(),
42 authority
: uri
.getAuthority(),
43 hostPort
: uri
.getHostPort(),
44 queryString
: uri
.getQueryString(),
45 relativePath
: uri
.getRelativePath(),
46 toString
: uri
.toString()
50 authority
: 'www.ietf.org',
51 hostPort
: 'www.ietf.org',
53 relativePath
: '/rfc/rfc2396.txt',
56 'construct composite components of URI on request'
62 QUnit
.test( 'Parse an ftp URI correctly with user and password', 1, function ( assert
) {
63 var uri
= new mw
.Uri( 'ftp://usr:pwd@192.0.2.16/' );
67 protocol
: uri
.protocol
,
69 password
: uri
.password
,
74 fragment
: uri
.fragment
86 'basic object properties'
90 QUnit
.test( 'Parse a uri with simple querystring', 1, function ( assert
) {
91 var uri
= new mw
.Uri( 'http://www.google.com/?q=uri' );
95 protocol
: uri
.protocol
,
100 fragment
: uri
.fragment
,
101 queryString
: uri
.getQueryString()
105 host
: 'www.google.com',
112 'basic object properties'
116 QUnit
.test( 'Handle multiple query parameter (overrideKeys on)', 5, function ( assert
) {
117 var uri
= new mw
.Uri( 'http://www.example.com/dir/?m=foo&m=bar&n=1', {
121 assert
.equal( uri
.query
.n
, '1', 'multiple parameters are parsed' );
122 assert
.equal( uri
.query
.m
, 'bar', 'last key overrides earlier keys' );
124 uri
.query
.n
= [ 'x', 'y', 'z' ];
126 // Verify parts and total length instead of entire string because order
127 // of iteration can vary.
128 assert
.ok( uri
.toString().indexOf( 'm=bar' ), 'toString preserves other values' );
129 assert
.ok( uri
.toString().indexOf( 'n=x&n=y&n=z' ), 'toString parameter includes all values of an array query parameter' );
130 assert
.equal( uri
.toString().length
, 'http://www.example.com/dir/?m=bar&n=x&n=y&n=z'.length
, 'toString matches expected string' );
133 QUnit
.test( 'Handle multiple query parameter (overrideKeys off)', 9, function ( assert
) {
134 var uri
= new mw
.Uri( 'http://www.example.com/dir/?m=foo&m=bar&n=1', {
138 // Strict comparison so that types are also verified (n should be string '1')
139 assert
.strictEqual( uri
.query
.m
.length
, 2, 'multi-value query should be an array with 2 items' );
140 assert
.strictEqual( uri
.query
.m
[0], 'foo', 'order and value is correct' );
141 assert
.strictEqual( uri
.query
.m
[1], 'bar', 'order and value is correct' );
142 assert
.strictEqual( uri
.query
.n
, '1', 'n=1 is parsed with the correct value of the expected type' );
144 // Change query values
145 uri
.query
.n
= [ 'x', 'y', 'z' ];
147 // Verify parts and total length instead of entire string because order
148 // of iteration can vary.
149 assert
.ok( uri
.toString().indexOf( 'm=foo&m=bar' ) >= 0, 'toString preserves other values' );
150 assert
.ok( uri
.toString().indexOf( 'n=x&n=y&n=z' ) >= 0, 'toString parameter includes all values of an array query parameter' );
151 assert
.equal( uri
.toString().length
, 'http://www.example.com/dir/?m=foo&m=bar&n=x&n=y&n=z'.length
, 'toString matches expected string' );
153 // Remove query values
154 uri
.query
.m
.splice( 0, 1 );
157 assert
.equal( uri
.toString(), 'http://www.example.com/dir/?m=bar', 'deletion properties' );
159 // Remove more query values, leaving an empty array
160 uri
.query
.m
.splice( 0, 1 );
161 assert
.equal( uri
.toString(), 'http://www.example.com/dir/', 'empty array value is ommitted' );
164 QUnit
.test( 'All-dressed URI with everything', 11, function ( assert
) {
165 var uri
, queryString
, relativePath
;
167 uri
= new mw
.Uri( 'http://auth@www.example.com:81/dir/dir.2/index.htm?q1=0&&test1&test2=value+%28escaped%29#top' );
171 protocol
: uri
.protocol
,
173 password
: uri
.password
,
178 fragment
: uri
.fragment
184 host
: 'www.example.com',
186 path
: '/dir/dir.2/index.htm',
187 query
: { q1
: '0', test1
: null, test2
: 'value (escaped)' },
190 'basic object properties'
193 assert
.equal( uri
.getUserInfo(), 'auth', 'user info' );
195 assert
.equal( uri
.getAuthority(), 'auth@www.example.com:81', 'authority equal to auth@hostport' );
197 assert
.equal( uri
.getHostPort(), 'www.example.com:81', 'hostport equal to host:port' );
199 queryString
= uri
.getQueryString();
200 assert
.ok( queryString
.indexOf( 'q1=0' ) >= 0, 'query param with numbers' );
201 assert
.ok( queryString
.indexOf( 'test1' ) >= 0, 'query param with null value is included' );
202 assert
.ok( queryString
.indexOf( 'test1=' ) === -1, 'query param with null value does not generate equals sign' );
203 assert
.ok( queryString
.indexOf( 'test2=value+%28escaped%29' ) >= 0, 'query param is url escaped' );
205 relativePath
= uri
.getRelativePath();
206 assert
.ok( relativePath
.indexOf( uri
.path
) >= 0, 'path in relative path' );
207 assert
.ok( relativePath
.indexOf( uri
.getQueryString() ) >= 0, 'query string in relative path' );
208 assert
.ok( relativePath
.indexOf( uri
.fragment
) >= 0, 'fragement in relative path' );
211 QUnit
.test( 'Cloning', 6, function ( assert
) {
214 original
= new mw
.Uri( 'http://foo.example.org/index.php?one=1&two=2' );
215 clone
= original
.clone();
217 assert
.deepEqual( clone
, original
, 'clone has equivalent properties' );
218 assert
.equal( original
.toString(), clone
.toString(), 'toString matches original' );
220 assert
.notStrictEqual( clone
, original
, 'clone is a different object when compared by reference' );
222 clone
.host
= 'bar.example.org';
223 assert
.notEqual( original
.host
, clone
.host
, 'manipulating clone did not effect original' );
224 assert
.notEqual( original
.toString(), clone
.toString(), 'Stringified url no longer matches original' );
226 clone
.query
.three
= 3;
230 { 'one': '1', 'two': '2' },
231 'Properties is deep cloned (bug 37708)'
235 QUnit
.test( 'Constructing mw.Uri from plain object', 3, function ( assert
) {
236 var uri
= new mw
.Uri({
238 host
: 'www.foo.local',
241 assert
.equal( uri
.toString(), 'http://www.foo.local/this', 'Basic properties' );
245 host
: 'www.foo.local',
247 query
: { hi
: 'there' },
250 assert
.equal( uri
.toString(), 'http://www.foo.local/this?hi=there#blah', 'More complex properties' );
254 var uri
= new mw
.Uri({
256 host
: 'www.foo.local'
260 return e
.message
=== 'Bad constructor arguments';
262 'Construction failed when missing required properties'
266 QUnit
.test( 'Manipulate properties', 8, function ( assert
) {
269 uriBase
= new mw
.Uri( 'http://en.wiki.local/w/api.php' );
271 uri
= uriBase
.clone();
272 uri
.fragment
= 'frag';
273 assert
.equal( uri
.toString(), 'http://en.wiki.local/w/api.php#frag', 'add a fragment' );
275 uri
= uriBase
.clone();
276 uri
.host
= 'fr.wiki.local';
278 assert
.equal( uri
.toString(), 'http://fr.wiki.local:8080/w/api.php', 'change host and port' );
280 uri
= uriBase
.clone();
281 uri
.query
.foo
= 'bar';
282 assert
.equal( uri
.toString(), 'http://en.wiki.local/w/api.php?foo=bar', 'add query arguments' );
284 delete uri
.query
.foo
;
285 assert
.equal( uri
.toString(), 'http://en.wiki.local/w/api.php', 'delete query arguments' );
287 uri
= uriBase
.clone();
288 uri
.query
.foo
= 'bar';
289 assert
.equal( uri
.toString(), 'http://en.wiki.local/w/api.php?foo=bar', 'extend query arguments' );
294 assert
.ok( uri
.toString().indexOf( 'foo=quux' ) >= 0, 'extend query arguments' );
295 assert
.ok( uri
.toString().indexOf( 'foo=bar' ) === -1, 'extend query arguments' );
296 assert
.ok( uri
.toString().indexOf( 'pif=paf' ) >= 0 , 'extend query arguments' );
299 QUnit
.test( 'Handle protocol-relative URLs', 5, function ( assert
) {
302 UriRel
= mw
.UriRelative( 'glork://en.wiki.local/foo.php' );
304 uri
= new UriRel( '//en.wiki.local/w/api.php' );
305 assert
.equal( uri
.protocol
, 'glork', 'create protocol-relative URLs with same protocol as document' );
307 uri
= new UriRel( '/foo.com' );
308 assert
.equal( uri
.toString(), 'glork://en.wiki.local/foo.com', 'handle absolute paths by supplying protocol and host from document in loose mode' );
310 uri
= new UriRel( 'http:/foo.com' );
311 assert
.equal( uri
.toString(), 'http://en.wiki.local/foo.com', 'handle absolute paths by supplying host from document in loose mode' );
313 uri
= new UriRel( '/foo.com', true );
314 assert
.equal( uri
.toString(), 'glork://en.wiki.local/foo.com', 'handle absolute paths by supplying protocol and host from document in strict mode' );
316 uri
= new UriRel( 'http:/foo.com', true );
317 assert
.equal( uri
.toString(), 'http://en.wiki.local/foo.com', 'handle absolute paths by supplying host from document in strict mode' );
320 QUnit
.test( 'Bad calls', 3, function ( assert
) {
325 new mw
.Uri( 'glaswegian penguins' );
328 return e
.message
=== 'Bad constructor arguments';
330 'throw error on non-URI as argument to constructor'
335 new mw
.Uri( 'foo.com/bar/baz', {
340 return e
.message
=== 'Bad constructor arguments';
342 'throw error on URI without protocol or // or leading / in strict mode'
345 uri
= new mw
.Uri( 'foo.com/bar/baz', {
348 assert
.equal( uri
.toString(), 'http://foo.com/bar/baz', 'normalize URI without protocol or // in loose mode' );
351 QUnit
.test( 'bug 35658', 2, function ( assert
) {
352 var testProtocol
, testServer
, testPort
, testPath
, UriClass
, uri
, href
;
354 testProtocol
= 'https://';
355 testServer
= 'foo.example.org';
359 UriClass
= mw
.UriRelative( testProtocol
+ testServer
+ '/some/path/index.html' );
360 uri
= new UriClass( testPath
);
361 href
= uri
.toString();
362 assert
.equal( href
, testProtocol
+ testServer
+ testPath
, 'Root-relative URL gets host & protocol supplied' );
364 UriClass
= mw
.UriRelative( testProtocol
+ testServer
+ ':' + testPort
+ '/some/path.php' );
365 uri
= new UriClass( testPath
);
366 href
= uri
.toString();
367 assert
.equal( href
, testProtocol
+ testServer
+ ':' + testPort
+ testPath
, 'Root-relative URL gets host, protocol, and port supplied' );
371 QUnit
.test( 'Constructor falls back to default location', 4, function ( assert
) {
372 var testuri
, MyUri
, uri
;
374 testuri
= 'http://example.org/w/index.php';
375 MyUri
= mw
.UriRelative( testuri
);
378 assert
.equal( uri
.toString(), testuri
, 'no arguments' );
380 uri
= new MyUri( undefined );
381 assert
.equal( uri
.toString(), testuri
, 'undefined' );
383 uri
= new MyUri( null );
384 assert
.equal( uri
.toString(), testuri
, 'null' );
386 uri
= new MyUri( '' );
387 assert
.equal( uri
.toString(), testuri
, 'empty string' );