/*!
* Parsoid utilities tests.
*
* @copyright 2011-2020 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
QUnit.module( 've.utils.parsoid', ve.test.utils.newMwEnvironment() );
QUnit.test( 'reduplicateStyles/deduplicateStyles', ( assert ) => {
// Test cases based on this page and the templates there:
// https://en.wikipedia.beta.wmflabs.org/wiki/Table_templated
const stylesCases = [
{
msg: 'styles are deduplicated',
deduplicated: `
`,
reduplicated: `
`
},
{
msg: 'styles in fosterable positions are NOT deduplicated, but they are emptied',
deduplicated: `
`,
reduplicated: `
`
}
];
stylesCases.forEach( ( caseItem ) => {
const doc = ve.createDocumentFromHtml( caseItem.deduplicated );
// Test that we can re-duplicate styles, which were de-duplicated in Parsoid HTML
mw.libs.ve.reduplicateStyles( doc.body );
assert.equalDomElement(
doc.body,
ve.createDocumentFromHtml( caseItem.reduplicated ).body,
caseItem.msg + ' (reduplicated)'
);
// Test that we can de-duplicate styles again, producing a result identical to the Parsoid HTML
mw.libs.ve.deduplicateStyles( doc.body );
assert.equalDomElement(
doc.body,
ve.createDocumentFromHtml( caseItem.deduplicated ).body,
caseItem.msg + ' (deduplicated)'
);
} );
} );
QUnit.test( 'getTargetDataFromHref', ( assert ) => {
const doc = ve.createDocumentFromHtml( ve.test.utils.makeBaseTag( ve.dm.mwExample.baseUri ) );
mw.config.set( {
wgScript: '/w/index.php',
wgArticlePath: '/wiki/$1'
} );
const hrefCases = [
{
msg: 'Parsoid link',
href: './Foo',
expected: {
title: 'Foo',
isInternal: true
}
},
{
msg: 'Parsoid red link',
href: './Foo?action=edit&redlink=1',
expected: {
title: 'Foo',
isInternal: true
}
},
{
msg: 'Parsoid link with fragment',
href: './Foo#Bar',
expected: {
title: 'Foo#Bar',
isInternal: true
}
},
{
msg: 'Parsoid red link with fragment',
href: './Foo?action=edit&redlink=1#Bar',
expected: {
title: 'Foo#Bar',
isInternal: true
}
},
{
msg: 'Old parser link',
href: '/wiki/Foo',
expected: {
title: 'Foo',
isInternal: true
}
},
{
msg: 'Old parser red link',
href: '/w/index.php?title=Foo&action=edit&redlink=1',
expected: {
title: 'Foo',
isInternal: true
}
},
{
msg: 'Old parser link with fragment',
href: '/wiki/Foo#Bar',
expected: {
title: 'Foo#Bar',
isInternal: true
}
},
{
msg: 'Old parser red link with fragment (old parser does not actually generate links like this, but we recognize them)',
href: '/w/index.php?title=Foo&action=edit&redlink=1#Bar',
expected: {
title: 'Foo#Bar',
isInternal: true
}
},
{
msg: 'Full URL link to current wiki',
href: 'http://example.com/wiki/Foo',
expected: {
title: 'Foo',
isInternal: true
}
},
{
msg: 'Full URL red link to current wiki',
href: 'http://example.com/w/index.php?title=Foo&action=edit&redlink=1',
expected: {
title: 'Foo',
isInternal: true
}
},
{
msg: 'Full URL link to current wiki with different protocol',
href: 'https://example.com/wiki/Foo',
expected: {
title: 'Foo',
isInternal: true
}
},
{
msg: 'Full URL link to current wiki, but with no title',
href: 'http://example.com/wiki/',
expected: {
title: '',
isInternal: true
}
},
{
msg: 'Full URL link to current wiki, but with extra parameters (1)',
href: 'http://example.com/wiki/Foo?action=history',
expected: {
isInternal: false
}
},
{
msg: 'Full URL link to current wiki, but with extra parameters (2)',
href: 'http://example.com/w/index.php?title=Foo&action=edit&redlink=1&preload=Blah',
expected: {
isInternal: false
}
},
{
msg: 'Full URL link to current wiki that may be valid, but uses a weird URL pattern',
href: 'http://example.com/wiki/?title=Foo',
expected: {
isInternal: false
}
},
{
msg: 'Full URL link to another wiki',
href: 'http://example.net/wiki/Foo',
expected: {
isInternal: false
}
},
{
msg: 'Full URL red link to another wiki',
href: 'http://example.net/w/index.php?title=Foo&action=edit&redlink=1',
expected: {
isInternal: false
}
},
{
/* eslint-disable no-script-url */
msg: 'Invalid protocol is handled as internal link',
href: 'javascript:alert()',
expected: {
title: 'javascript:alert()',
isInternal: true
}
/* eslint-enable no-script-url */
},
{
msg: 'Invalid protocol is handled as internal link',
href: 'not-a-protocol:Some%20text',
expected: {
title: 'not-a-protocol:Some text',
isInternal: true
}
},
{
msg: 'Valid protocol is handled as external link',
href: 'https://example.net/',
expected: {
isInternal: false
}
},
{
msg: 'Valid protocol is handled as external link',
href: 'mailto:example@example.net',
expected: {
isInternal: false
}
}
];
hrefCases.forEach( ( caseItem ) => {
const actualInfo = mw.libs.ve.getTargetDataFromHref( caseItem.href, doc );
assert.deepEqual( actualInfo, caseItem.expected, caseItem.msg );
} );
} );