use example.com, the RFC-2606 guaranteed example url. followup to r99446
[lhc/web/wiklou.git] / tests / jasmine / spec / mediawiki.Uri.spec.js
1 ( function() {
2
3 // ensure we have a generic URI parser if not running in a browser
4 if ( !mw.Uri ) {
5 mw.Uri = mw.UriRelative( 'http://example.com/' );
6 }
7
8 describe( "mw.Uri", function() {
9
10 describe( "should work well in loose and strict mode", function() {
11
12 function basicTests( strict ) {
13
14 describe( "should parse a simple HTTP URI correctly", function() {
15
16 var uriString = 'http://www.ietf.org/rfc/rfc2396.txt';
17 var uri;
18 if ( strict ) {
19 uri = new mw.Uri( uriString, strict );
20 } else {
21 uri = new mw.Uri( uriString );
22 }
23
24 it( "should have basic object properties", function() {
25 expect( uri.protocol ).toEqual( 'http' );
26 expect( uri.host ).toEqual( 'www.ietf.org' );
27 expect( uri.port ).not.toBeDefined();
28 expect( uri.path ).toEqual( '/rfc/rfc2396.txt' );
29 expect( uri.query ).toEqual( {} );
30 expect( uri.fragment ).not.toBeDefined();
31 } );
32
33 describe( "should construct composite components of URI on request", function() {
34 it( "should have empty userinfo", function() {
35 expect( uri.getUserInfo() ).toEqual( '' );
36 } );
37
38 it( "should have authority equal to host", function() {
39 expect( uri.getAuthority() ).toEqual( 'www.ietf.org' );
40 } );
41
42 it( "should have hostport equal to host", function() {
43 expect( uri.getHostPort() ).toEqual( 'www.ietf.org' );
44 } );
45
46 it( "should have empty string as query string", function() {
47 expect( uri.getQueryString() ).toEqual( '' );
48 } );
49
50 it( "should have path as relative path", function() {
51 expect( uri.getRelativePath() ).toEqual( '/rfc/rfc2396.txt' );
52 } );
53
54 it( "should return a uri string equivalent to original", function() {
55 expect( uri.toString() ).toEqual( uriString );
56 } );
57 } );
58 } );
59 }
60
61 describe( "should work in loose mode", function() {
62 basicTests( false );
63 } );
64
65 describe( "should work in strict mode", function() {
66 basicTests( true );
67 } );
68
69 } );
70
71 it( "should parse a simple ftp URI correctly with user and password", function() {
72 var uri = new mw.Uri( 'ftp://usr:pwd@192.0.2.16/' );
73 expect( uri.protocol ).toEqual( 'ftp' );
74 expect( uri.user ).toEqual( 'usr' );
75 expect( uri.password ).toEqual( 'pwd' );
76 expect( uri.host ).toEqual( '192.0.2.16' );
77 expect( uri.port ).not.toBeDefined();
78 expect( uri.path ).toEqual( '/' );
79 expect( uri.query ).toEqual( {} );
80 expect( uri.fragment ).not.toBeDefined();
81 } );
82
83 it( "should parse a simple querystring", function() {
84 var uri = new mw.Uri( 'http://www.google.com/?q=uri' );
85 expect( uri.protocol ).toEqual( 'http' );
86 expect( uri.host ).toEqual( 'www.google.com' );
87 expect( uri.port ).not.toBeDefined();
88 expect( uri.path ).toEqual( '/' );
89 expect( uri.query ).toBeDefined();
90 expect( uri.query ).toEqual( { q: 'uri' } );
91 expect( uri.fragment ).not.toBeDefined();
92 expect( uri.getQueryString() ).toEqual( 'q=uri' );
93 } );
94
95 describe( "should handle multiple value query args (overrideKeys on)", function() {
96 var uri = new mw.Uri( 'http://www.sample.com/dir/?m=foo&m=bar&n=1', { overrideKeys: true } );
97 it ( "should parse with multiple values", function() {
98 expect( uri.query.m ).toEqual( 'bar' );
99 expect( uri.query.n ).toEqual( '1' );
100 } );
101 it ( "should accept multiple values", function() {
102 uri.query.n = [ "x", "y", "z" ];
103 expect( uri.toString() ).toContain( 'm=bar' );
104 expect( uri.toString() ).toContain( 'n=x&n=y&n=z' );
105 expect( uri.toString().length ).toEqual( 'http://www.sample.com/dir/?m=bar&n=x&n=y&n=z'.length );
106 } );
107 } );
108
109 describe( "should handle multiple value query args (overrideKeys off)", function() {
110 var uri = new mw.Uri( 'http://www.sample.com/dir/?m=foo&m=bar&n=1', { overrideKeys: false } );
111 it ( "should parse with multiple values", function() {
112 expect( uri.query.m.length ).toEqual( 2 );
113 expect( uri.query.m[0] ).toEqual( 'foo' );
114 expect( uri.query.m[1] ).toEqual( 'bar' );
115 expect( uri.query.n ).toEqual( '1' );
116 } );
117 it ( "should accept multiple values", function() {
118 uri.query.n = [ "x", "y", "z" ];
119 expect( uri.toString() ).toContain( 'm=foo&m=bar' );
120 expect( uri.toString() ).toContain( 'n=x&n=y&n=z' );
121 expect( uri.toString().length ).toEqual( 'http://www.sample.com/dir/?m=foo&m=bar&n=x&n=y&n=z'.length );
122 } );
123 it ( "should be okay with removing values", function() {
124 uri.query.m.splice( 0, 1 );
125 delete uri.query.n;
126 expect( uri.toString() ).toEqual( 'http://www.sample.com/dir/?m=bar' );
127 uri.query.m.splice( 0, 1 );
128 expect( uri.toString() ).toEqual( 'http://www.sample.com/dir/' );
129 } );
130 } );
131
132 describe( "should deal with an all-dressed URI with everything", function() {
133 var uri = new mw.Uri( 'http://auth@www.sample.com:81/dir/dir.2/index.htm?q1=0&&test1&test2=value+%28escaped%29#top' );
134
135 it( "should have basic object properties", function() {
136 expect( uri.protocol ).toEqual( 'http' );
137 expect( uri.user ).toEqual( 'auth' );
138 expect( uri.password ).not.toBeDefined();
139 expect( uri.host ).toEqual( 'www.sample.com' );
140 expect( uri.port ).toEqual( '81' );
141 expect( uri.path ).toEqual( '/dir/dir.2/index.htm' );
142 expect( uri.query ).toEqual( { q1: '0', test1: null, test2: 'value (escaped)' } );
143 expect( uri.fragment ).toEqual( 'top' );
144 } );
145
146 describe( "should construct composite components of URI on request", function() {
147 it( "should have userinfo", function() {
148 expect( uri.getUserInfo() ).toEqual( 'auth' );
149 } );
150
151 it( "should have authority equal to auth@hostport", function() {
152 expect( uri.getAuthority() ).toEqual( 'auth@www.sample.com:81' );
153 } );
154
155 it( "should have hostport equal to host:port", function() {
156 expect( uri.getHostPort() ).toEqual( 'www.sample.com:81' );
157 } );
158
159 it( "should have query string which contains all components", function() {
160 var queryString = uri.getQueryString();
161 expect( queryString ).toContain( 'q1=0' );
162 expect( queryString ).toContain( 'test1' );
163 expect( queryString ).not.toContain( 'test1=' );
164 expect( queryString ).toContain( 'test2=value+%28escaped%29' );
165 } );
166
167 it( "should have path as relative path", function() {
168 expect( uri.getRelativePath() ).toContain( uri.path );
169 expect( uri.getRelativePath() ).toContain( uri.getQueryString() );
170 expect( uri.getRelativePath() ).toContain( uri.fragment );
171 } );
172
173 } );
174 } );
175
176 describe( "should be able to clone itself", function() {
177 var original = new mw.Uri( 'http://en.wiki.local/w/api.php?action=query&foo=bar' );
178 var clone = original.clone();
179
180 it( "should make clones equivalent", function() {
181 expect( original ).toEqual( clone );
182 expect( original.toString() ).toEqual( clone.toString() );
183 } );
184
185 it( "should be able to manipulate clones independently", function() {
186 // but they are still different objects
187 expect( original ).not.toBe( clone );
188 // and can diverge
189 clone.host = 'fr.wiki.local';
190 expect( original.host ).not.toEqual( clone.host );
191 expect( original.toString() ).not.toEqual( clone.toString() );
192 } );
193 } );
194
195 describe( "should be able to construct URL from object", function() {
196 it ( "should construct given basic arguments", function() {
197 var uri = new mw.Uri( { protocol: 'http', host: 'www.foo.local', path: '/this' } );
198 expect( uri.toString() ).toEqual( 'http://www.foo.local/this' );
199 } );
200
201 it ( "should construct given more complex arguments", function() {
202 var uri = new mw.Uri( {
203 protocol: 'http',
204 host: 'www.foo.local',
205 path: '/this',
206 query: { hi: 'there' },
207 fragment: 'blah'
208 } );
209 expect( uri.toString() ).toEqual( 'http://www.foo.local/this?hi=there#blah' );
210 } );
211
212 it ( "should fail to construct without required properties", function() {
213 expect( function() {
214 var uri = new mw.Uri( { protocol: 'http', host: 'www.foo.local' } );
215 } ).toThrow( "Bad constructor arguments" );
216 } );
217 } );
218
219 describe( "should be able to manipulate properties", function() {
220 var uri;
221
222 beforeEach( function() {
223 uri = new mw.Uri( 'http://en.wiki.local/w/api.php' );
224 } );
225
226 it( "can add a fragment", function() {
227 uri.fragment = 'frag';
228 expect( uri.toString() ).toEqual( 'http://en.wiki.local/w/api.php#frag' );
229 } );
230
231 it( "can change host and port", function() {
232 uri.host = 'fr.wiki.local';
233 uri.port = '8080';
234 expect( uri.toString() ).toEqual( 'http://fr.wiki.local:8080/w/api.php' );
235 } );
236
237 it ( "can add query arguments", function() {
238 uri.query.foo = 'bar';
239 expect( uri.toString() ).toEqual( 'http://en.wiki.local/w/api.php?foo=bar' );
240 } );
241
242 it ( "can extend query arguments", function() {
243 uri.query.foo = 'bar';
244 expect( uri.toString() ).toEqual( 'http://en.wiki.local/w/api.php?foo=bar' );
245 uri.extend( { foo: 'quux', pif: 'paf' } );
246 expect( uri.toString() ).toContain( 'foo=quux' );
247 expect( uri.toString() ).not.toContain( 'foo=bar' );
248 expect( uri.toString() ).toContain( 'pif=paf' );
249 } );
250
251 it ( "can remove query arguments", function() {
252 uri.query.foo = 'bar';
253 expect( uri.toString() ).toEqual( 'http://en.wiki.local/w/api.php?foo=bar' );
254 delete( uri.query.foo );
255 expect( uri.toString() ).toEqual( 'http://en.wiki.local/w/api.php' );
256 } );
257
258 } );
259
260 describe( "should handle protocol-relative URLs", function() {
261
262 it ( "should create protocol-relative URLs with same protocol as document", function() {
263 var uriRel = mw.UriRelative( 'glork://en.wiki.local/foo.php' );
264 var uri = new uriRel( '//en.wiki.local/w/api.php' );
265 expect( uri.protocol ).toEqual( 'glork' );
266 } );
267
268 } );
269
270 it( "should throw error on no arguments to constructor", function() {
271 expect( function() {
272 var uri = new mw.Uri();
273 } ).toThrow( "Bad constructor arguments" );
274 } );
275
276 it( "should throw error on empty string as argument to constructor", function() {
277 expect( function() {
278 var uri = new mw.Uri( '' );
279 } ).toThrow( "Bad constructor arguments" );
280 } );
281
282 it( "should throw error on non-URI as argument to constructor", function() {
283 expect( function() {
284 var uri = new mw.Uri( 'glaswegian penguins' );
285 } ).toThrow( "Bad constructor arguments" );
286 } );
287
288 it( "should throw error on improper URI as argument to constructor", function() {
289 expect( function() {
290 var uri = new mw.Uri( 'http:/foo.com' );
291 } ).toThrow( "Bad constructor arguments" );
292 } );
293
294 it( "should throw error on URI without protocol or // in strict mode", function() {
295 expect( function() {
296 var uri = new mw.Uri( 'foo.com/bar/baz', true );
297 } ).toThrow( "Bad constructor arguments" );
298 } );
299
300 it( "should normalize URI without protocol or // in loose mode", function() {
301 var uri = new mw.Uri( 'foo.com/bar/baz', false );
302 expect( uri.toString() ).toEqual( 'http://foo.com/bar/baz' );
303 } );
304
305 } );
306
307 } )();