(bug 35658) make mw.Uri handle uris w/o protocol or host
authorlupo <lupo.bugzilla@gmail.com>
Sat, 7 Apr 2012 16:52:02 +0000 (18:52 +0200)
committerlupo <lupo.bugzilla@gmail.com>
Sat, 7 Apr 2012 16:52:02 +0000 (18:52 +0200)
Includes testcase.

mw.Uri already supplied the protocol if it was missing and
document.location was set. Newly it also supplies the host (and port)
from document.location if that is set. That enables handling of
root-relative URls like "/some/path".

Changeset 2/3: rename test file from mediaWiki.Uri.test.js to
mediawiki.Uri.test.js.

Changeset 4: fix jasmine tests. Test for 'http:/foo.com' is now expected
to succeed, not throw an exception. The second test for
'foo.com/bar/baz' in strict mode is correct; that's parsed in strict
mode as a truly relative path.

Change-Id: Ibc4386ba40cffea9d30417ec2720114f6819ae1c

resources/mediawiki/mediawiki.Uri.js
tests/jasmine/spec/mediawiki.Uri.spec.js
tests/qunit/QUnitTestResources.php
tests/qunit/suites/resources/mediawiki/mediawiki.Uri.test.js [new file with mode: 0644]

index 26fdfa9..2957674 100644 (file)
 
                        // protocol-relative URLs
                        if ( !this.protocol ) {
-                               this.protocol = defaultProtocol;
+                               this.protocol = defaultUri.protocol;
+                       }
+                       // No host given:
+                       if ( !this.host ) {
+                               this.host = defaultUri.host;
+                               // port ?
+                               if ( !this.port ) {
+                                       this.port = defaultUri.port;
+                               }
+                       }
+                       if ( this.path && this.path.charAt( 0 ) !== '/' ) {
+                               // A real relative URL, relative to defaultUri.path. We can't really handle that since we cannot
+                               // figure out whether the last path compoennt of defaultUri.path is a directory or a file.
+                               throw new Error( 'Bad constructor arguments' );
                        }
-
                        if ( !( this.protocol && this.host && this.path ) ) {
                                throw new Error( 'Bad constructor arguments' );
                        }
                        }
                };
 
-               var defaultProtocol = ( new Uri( documentLocation ) ).protocol;
+               var defaultUri = new Uri( documentLocation );
 
                return Uri;     
        };
index 721ccb3..e396ab3 100644 (file)
                } );
 
                describe( "should handle protocol-relative URLs", function() { 
+                       var uriRel = mw.UriRelative( 'glork://en.wiki.local/foo.php' );
 
                        it ( "should create protocol-relative URLs with same protocol as document", function() {
-                               var uriRel = mw.UriRelative( 'glork://en.wiki.local/foo.php' );
                                var uri = new uriRel( '//en.wiki.local/w/api.php' );
                                expect( uri.protocol ).toEqual( 'glork' );
                        } );
 
+                       it( "should handle absolute paths by supplying protocol and host from document in loose mode", function() {
+                               var uri = new uriRel( '/foo.com' );
+                               expect( uri.toString() ).toEqual( 'glork://en.wiki.local/foo.com' );
+                       } );
+
+                       it( "should handle absolute paths by supplying host from document in loose mode", function() {
+                               var uri = new uriRel( 'http:/foo.com' );
+                               expect( uri.toString() ).toEqual( 'http://en.wiki.local/foo.com' );
+                       } );
+
+                       it( "should handle absolute paths by supplying protocol and host from document in strict mode", function() {
+                               var uri = new uriRel( '/foo.com', true );
+                               expect( uri.toString() ).toEqual( 'glork://en.wiki.local/foo.com' );
+                       } );
+
+                       it( "should handle absolute paths by supplying host from document in strict mode", function() {
+                               var uri = new uriRel( 'http:/foo.com', true );
+                               expect( uri.toString() ).toEqual( 'http://en.wiki.local/foo.com' );
+                       } );
                } );
 
                it( "should throw error on no arguments to constructor", function() {
                        } ).toThrow( "Bad constructor arguments" );
                } );
 
-               it( "should throw error on improper URI as argument to constructor", function() {
-                       expect( function() { 
-                               var uri = new mw.Uri( 'http:/foo.com' );
-                       } ).toThrow( "Bad constructor arguments" );
-               } );
-
-               it( "should throw error on URI without protocol or // in strict mode", function() {
+               it( "should throw error on URI without protocol or // or leading / in strict mode", function() {
                        expect( function() { 
                                var uri = new mw.Uri( 'foo.com/bar/baz', true );
                        } ).toThrow( "Bad constructor arguments" );
index 687ad44..9e1e9b2 100644 (file)
@@ -22,6 +22,7 @@ return array(
                        'tests/qunit/suites/resources/mediawiki/mediawiki.jscompat.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js',
+                       'tests/qunit/suites/resources/mediawiki/mediawiki.Uri.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.user.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js',
                        'tests/qunit/suites/resources/mediawiki.special/mediawiki.special.recentchanges.test.js',
@@ -43,6 +44,7 @@ return array(
                        'jquery.textSelection',
                        'mediawiki',
                        'mediawiki.Title',
+                       'mediawiki.Uri',
                        'mediawiki.user',
                        'mediawiki.util',
                        'mediawiki.special.recentchanges',
diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.Uri.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.Uri.test.js
new file mode 100644 (file)
index 0000000..fcdcd21
--- /dev/null
@@ -0,0 +1,27 @@
+module( 'mediawiki.Uri', QUnit.newMwEnvironment() );
+
+test( '-- Initial check', function() {
+       expect( 1 );
+
+       ok( mw.UriRelative, 'mw.Uri defined' );
+} );
+
+test( 'mw.Uri bug 35658', function() {
+       expect( 2 );
+
+       var testProtocol = 'https://';
+       var testServer = 'foo.example.org';
+       var testPort = '3004';
+       var testPath = '/!1qy';
+
+       var uriClass = mw.UriRelative( testProtocol + testServer + '/some/path/index.html' );
+       var uri = new uriClass( testPath );
+       var href = uri.toString();
+       equal( href, testProtocol + testServer + testPath, 'Root-relative URL gets host & protocol supplied' );
+
+       uriClass = mw.UriRelative( testProtocol + testServer + ':' + testPort + '/some/path.php' );
+       uri = new uriClass( testPath );
+       href = uri.toString();
+       equal( href, testProtocol + testServer + ':' + testPort + testPath, 'Root-relative URL gets host, protocol, and port supplied' );
+
+} );