2019-07-02 21:10:10 +00:00
|
|
|
( function () {
|
2024-03-24 20:53:43 +00:00
|
|
|
const TitleUtil = require( '../../../resources/skins.minerva.scripts/TitleUtil.js' );
|
|
|
|
const mwUriOrg = mw.Uri;
|
2019-03-04 22:19:33 +00:00
|
|
|
|
|
|
|
QUnit.module( 'Minerva TitleUtil', QUnit.newMwEnvironment( {
|
2022-05-15 00:27:53 +00:00
|
|
|
beforeEach: function () {
|
2019-03-04 22:19:33 +00:00
|
|
|
this.mwUriOrg = mw.Uri;
|
|
|
|
mw.Uri = mw.UriRelative( 'https://meta.wikimedia.org/w/index.php' );
|
2022-05-15 00:41:24 +00:00
|
|
|
mw.config.set( {
|
|
|
|
wgArticlePath: '/wiki/$1',
|
|
|
|
wgScriptPath: '/w'
|
|
|
|
} );
|
2019-03-04 22:19:33 +00:00
|
|
|
},
|
2022-05-15 00:27:53 +00:00
|
|
|
afterEach: function () {
|
2022-05-15 00:41:24 +00:00
|
|
|
mw.Uri = mwUriOrg;
|
2022-08-18 07:46:25 +00:00
|
|
|
},
|
|
|
|
// mw.Title relies on these three config vars
|
|
|
|
// Restore them after each test run
|
|
|
|
config: {
|
|
|
|
wgFormattedNamespaces: {
|
|
|
|
'-2': 'Media',
|
|
|
|
'-1': 'Special',
|
|
|
|
0: '',
|
|
|
|
1: 'Talk',
|
|
|
|
2: 'User',
|
|
|
|
3: 'User talk',
|
|
|
|
4: 'Wikipedia',
|
|
|
|
5: 'Wikipedia talk',
|
|
|
|
6: 'File',
|
|
|
|
7: 'File talk',
|
|
|
|
8: 'MediaWiki',
|
|
|
|
9: 'MediaWiki talk',
|
|
|
|
10: 'Template',
|
|
|
|
11: 'Template talk',
|
|
|
|
12: 'Help',
|
|
|
|
13: 'Help talk',
|
|
|
|
14: 'Category',
|
|
|
|
15: 'Category talk',
|
|
|
|
// testing custom / localized namespace
|
|
|
|
100: 'Penguins'
|
|
|
|
},
|
|
|
|
wgNamespaceIds: {
|
|
|
|
/* eslint-disable camelcase */
|
|
|
|
media: -2,
|
|
|
|
special: -1,
|
|
|
|
'': 0,
|
|
|
|
talk: 1,
|
|
|
|
user: 2,
|
|
|
|
user_talk: 3,
|
|
|
|
wikipedia: 4,
|
|
|
|
wikipedia_talk: 5,
|
|
|
|
file: 6,
|
|
|
|
file_talk: 7,
|
|
|
|
mediawiki: 8,
|
|
|
|
mediawiki_talk: 9,
|
|
|
|
template: 10,
|
|
|
|
template_talk: 11,
|
|
|
|
help: 12,
|
|
|
|
help_talk: 13,
|
|
|
|
category: 14,
|
|
|
|
category_talk: 15,
|
|
|
|
image: 6,
|
|
|
|
image_talk: 7,
|
|
|
|
project: 4,
|
|
|
|
project_talk: 5,
|
|
|
|
// Testing custom namespaces and aliases
|
|
|
|
penguins: 100,
|
|
|
|
antarctic_waterfowl: 100
|
|
|
|
/* eslint-enable camelcase */
|
|
|
|
},
|
|
|
|
wgCaseSensitiveNamespaces: []
|
2019-03-04 22:19:33 +00:00
|
|
|
}
|
|
|
|
} ) );
|
|
|
|
|
2022-05-15 00:41:24 +00:00
|
|
|
QUnit.test.each( '.newFromUri() authority', {
|
|
|
|
empty: '',
|
|
|
|
metawiki: 'https://meta.wikimedia.org'
|
2024-06-03 12:06:43 +00:00
|
|
|
}, ( assert, authority ) => {
|
2024-03-24 20:53:43 +00:00
|
|
|
const validateReadOnlyLink = { validateReadOnlyLink: true };
|
2022-05-15 00:41:24 +00:00
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( authority + '/w/index.php?title=Title' ).getPrefixedDb(),
|
|
|
|
'Title',
|
|
|
|
'title is in query parameter'
|
|
|
|
);
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( authority + '/wiki/Title' ).getPrefixedDb(),
|
|
|
|
'Title',
|
|
|
|
'title is in path'
|
|
|
|
);
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( authority + '/foo/bar/wiki/Title' ),
|
|
|
|
null,
|
|
|
|
'title is not in nonmatching path'
|
|
|
|
);
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( authority + '/wiki/%E6%B8%AC%E8%A9%A6' ).getPrefixedDb(),
|
|
|
|
'測試',
|
|
|
|
'title is decoded'
|
|
|
|
);
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( authority + '/wiki/Foo bar' ).getPrefixedDb(),
|
|
|
|
'Foo_bar',
|
|
|
|
'title with space is decoded'
|
|
|
|
);
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( authority + '/wiki/Foo%20bar' ).getPrefixedDb(),
|
|
|
|
'Foo_bar',
|
|
|
|
'title with encoded space is decoded'
|
|
|
|
);
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( authority + '/w/index.php?title=Title#fragment' ).getPrefixedDb(),
|
|
|
|
'Title',
|
|
|
|
'fragment is omitted from query title'
|
|
|
|
);
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( authority + '/wiki/Title#fragment' ).getPrefixedDb(),
|
|
|
|
'Title',
|
|
|
|
'fragment is omitted from path title'
|
|
|
|
);
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( authority + '/w/index.php?title=Title#fragment' ).getFragment(),
|
|
|
|
'fragment',
|
|
|
|
'fragment is present after query parameter'
|
|
|
|
);
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( authority + '/wiki/Title#fragment' ).getFragment(),
|
|
|
|
'fragment',
|
|
|
|
'fragment is present after path'
|
|
|
|
);
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( authority + '/w/index.php?title=Title#foo%20bar' ).getFragment(),
|
|
|
|
'foo bar',
|
|
|
|
'fragment is decoded'
|
|
|
|
);
|
2019-03-04 22:19:33 +00:00
|
|
|
|
2022-05-15 00:41:24 +00:00
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( authority + '/w/index.php?title=Title', validateReadOnlyLink ).getPrefixedDb(),
|
|
|
|
'Title',
|
|
|
|
'query title is read-only'
|
|
|
|
);
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( authority + '/wiki/Title', validateReadOnlyLink ).getPrefixedDb(),
|
|
|
|
'Title',
|
|
|
|
'path title is read-only'
|
|
|
|
);
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( authority + '/w/index.php?title=Title&oldid=123', validateReadOnlyLink ).getPrefixedDb(),
|
|
|
|
'Title',
|
|
|
|
'query title with revision is read-only'
|
|
|
|
);
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( authority + '/w/index.php?title=Title¶m', validateReadOnlyLink ),
|
|
|
|
null,
|
|
|
|
'query title with unknown parameter is not read-only'
|
|
|
|
);
|
|
|
|
} );
|
2019-03-04 22:19:33 +00:00
|
|
|
|
2022-05-15 00:41:24 +00:00
|
|
|
QUnit.test.each( '.newFromUri() bad input', [
|
|
|
|
'%', null, undefined, '', ' ', '/', {}, '\\', '/wiki/%', '/w/index.php?title=%'
|
2024-06-03 12:06:43 +00:00
|
|
|
], ( assert, input ) => {
|
2022-05-15 00:41:24 +00:00
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( input ),
|
|
|
|
null,
|
|
|
|
'no Title in bad input input="' + input + '"'
|
|
|
|
);
|
|
|
|
} );
|
2019-03-04 22:19:33 +00:00
|
|
|
|
2024-06-03 12:06:43 +00:00
|
|
|
QUnit.test( '.newFromUri() misc', ( assert ) => {
|
2019-03-04 22:19:33 +00:00
|
|
|
// Parameters are passed to Uri's constructor.
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( { protocol: 'https',
|
|
|
|
host: 'meta.wikimedia.org',
|
|
|
|
path: '/wiki/Title' } ).getPrefixedDb(),
|
|
|
|
'Title',
|
|
|
|
'title is in Uri parameters'
|
|
|
|
);
|
|
|
|
|
|
|
|
// A Uri itself can be passed.
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( new mw.Uri( 'https://meta.wikimedia.org/wiki/Title' ) ).getPrefixedDb(),
|
|
|
|
'Title',
|
|
|
|
'title is in Uri'
|
|
|
|
);
|
|
|
|
|
|
|
|
// JSDoc examples.
|
|
|
|
// https://meta.wikimedia.org/wiki/Foo → Foo (path title)
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( 'https://meta.wikimedia.org/wiki/Foo' ).getPrefixedDb(),
|
|
|
|
'Foo',
|
|
|
|
'path title'
|
|
|
|
);
|
|
|
|
|
|
|
|
// http://meta.wikimedia.org/wiki/Foo → Foo (mismatching protocol)
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( 'http://meta.wikimedia.org/wiki/Foo' ).getPrefixedDb(),
|
|
|
|
'Foo',
|
|
|
|
'mismatching protocol'
|
|
|
|
);
|
|
|
|
|
|
|
|
// /wiki/Foo → Foo (relative URI)
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( '/wiki/Foo' ).getPrefixedDb(),
|
|
|
|
'Foo',
|
|
|
|
'relative URI'
|
|
|
|
);
|
|
|
|
|
|
|
|
// /w/index.php?title=Foo → Foo (title query parameter)
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( '/w/index.php?title=Foo' ).getPrefixedDb(),
|
|
|
|
'Foo',
|
|
|
|
'title query parameter'
|
|
|
|
);
|
|
|
|
|
|
|
|
// /wiki/Talk:Foo → Talk:Foo (non-main namespace URI)
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( '/wiki/Talk:Foo' ).getPrefixedDb(),
|
|
|
|
'Talk:Foo',
|
|
|
|
'non-main namespace URI'
|
|
|
|
);
|
|
|
|
|
|
|
|
// /wiki/Foo bar → Foo_bar (name with spaces)
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( '/wiki/Foo bar' ).getPrefixedDb(),
|
|
|
|
'Foo_bar',
|
|
|
|
'name with spaces'
|
|
|
|
);
|
|
|
|
|
|
|
|
// /wiki/Foo%20bar → Foo_bar (name with percent encoded spaces)
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( '/wiki/Foo%20bar' ).getPrefixedDb(),
|
|
|
|
'Foo_bar',
|
|
|
|
'name with percent encoded spaces'
|
|
|
|
);
|
|
|
|
|
|
|
|
// /wiki/Foo+bar → Foo+bar (name with +)
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( '/wiki/Foo+bar' ).getPrefixedDb(),
|
|
|
|
'Foo+bar',
|
|
|
|
'name with +'
|
|
|
|
);
|
|
|
|
|
|
|
|
// /w/index.php?title=Foo%2bbar → Foo+bar (query parameter with +)
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( '/w/index.php?title=Foo%2bbar' ).getPrefixedDb(),
|
|
|
|
'Foo+bar',
|
|
|
|
'query parameter with +'
|
|
|
|
);
|
|
|
|
|
|
|
|
// / → null (mismatching article path)
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( '/' ),
|
|
|
|
null,
|
|
|
|
'mismatching article path'
|
|
|
|
);
|
|
|
|
|
|
|
|
// /wiki/index.php?title=Foo → null (mismatching script path)
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( '/wiki/index.php?title=Foo' ),
|
|
|
|
null,
|
|
|
|
'mismatching script path'
|
|
|
|
);
|
|
|
|
|
|
|
|
// https://archive.org/ → null (mismatching host)
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( 'https://archive.org/' ),
|
|
|
|
null,
|
|
|
|
'mismatching host (0)'
|
|
|
|
);
|
|
|
|
|
|
|
|
// https://foo.wikimedia.org/ → null (mismatching host)
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( 'https://foo.wikimedia.org/' ),
|
|
|
|
null,
|
|
|
|
'mismatching host (1)'
|
|
|
|
);
|
|
|
|
|
|
|
|
// https://en.wikipedia.org/wiki/Bar → null (mismatching host)
|
|
|
|
assert.strictEqual(
|
|
|
|
TitleUtil.newFromUri( 'https://en.wikipedia.org/wiki/Bar' ),
|
|
|
|
null,
|
|
|
|
'mismatching host (2)'
|
|
|
|
);
|
|
|
|
} );
|
2019-07-02 21:10:10 +00:00
|
|
|
}() );
|