2015-03-25 20:53:27 +00:00
|
|
|
( function ( $, mw ) {
|
|
|
|
|
|
|
|
QUnit.module( 'ext.popups.core', QUnit.newMwEnvironment( {
|
|
|
|
config: {
|
|
|
|
wgArticlePath: '/wiki/$1'
|
|
|
|
}
|
|
|
|
} ) );
|
|
|
|
|
|
|
|
QUnit.test( 'getTitle', function ( assert ) {
|
|
|
|
var cases, i, expected, actual;
|
|
|
|
|
2015-04-09 01:16:09 +00:00
|
|
|
QUnit.expect( 11 );
|
2015-03-25 20:53:27 +00:00
|
|
|
cases = [
|
|
|
|
[ '/wiki/Foo', 'Foo' ],
|
|
|
|
[ '/wiki/Foo#Bar', 'Foo' ],
|
|
|
|
[ '/wiki/Foo?oldid=1', undefined ],
|
|
|
|
[ '/wiki/%E6%B8%AC%E8%A9%A6', '測試' ],
|
|
|
|
[ '/w/index.php?title=Foo', 'Foo' ],
|
|
|
|
[ '/w/index.php?title=Foo#Bar', 'Foo' ],
|
|
|
|
[ '/w/Foo?title=Foo&action=edit', undefined ],
|
|
|
|
[ '/w/index.php?title=%E6%B8%AC%E8%A9%A6', '測試' ],
|
|
|
|
[ '/w/index.php?oldid=1', undefined ],
|
2015-04-09 01:16:09 +00:00
|
|
|
[ '/Foo', undefined ],
|
|
|
|
/*jshint -W107 */
|
|
|
|
[ 'javascript:void(0);', undefined ]
|
|
|
|
/*jshint +W107 */
|
2015-03-25 20:53:27 +00:00
|
|
|
];
|
|
|
|
|
|
|
|
for ( i = 0; i < cases.length; i++ ) {
|
2015-08-26 10:15:16 +00:00
|
|
|
expected = cases[ i ][ 1 ];
|
|
|
|
actual = mw.popups.getTitle( cases[ i ][ 0 ] );
|
2015-03-25 20:53:27 +00:00
|
|
|
assert.equal( actual, expected );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
|
2016-04-13 21:21:38 +00:00
|
|
|
QUnit.test( 'removeTooltips', function ( assert ) {
|
|
|
|
var $link = $( '<a>', {
|
|
|
|
text: 'link with tooltip',
|
|
|
|
title: 'link title',
|
|
|
|
href: '#' // `href` is needed for testing the `focus` event
|
|
|
|
} ).appendTo( 'body' );
|
|
|
|
|
|
|
|
QUnit.expect( 5 );
|
|
|
|
|
|
|
|
mw.popups.removeTooltips( $link );
|
|
|
|
|
|
|
|
$link.trigger( 'mouseenter' );
|
|
|
|
assert.equal( $link.attr( 'title' ), '', 'The link does not have a title on mouseenter.' );
|
|
|
|
|
|
|
|
$link.trigger( 'mouseleave' );
|
|
|
|
assert.equal( $link.attr( 'title' ), 'link title', 'The link has a title on mouseleave.' );
|
|
|
|
|
|
|
|
$link.trigger( 'focus' );
|
|
|
|
assert.equal( $link.attr( 'title' ), '', 'The link does not have a title on focus.' );
|
|
|
|
|
|
|
|
$link.trigger( 'blur' );
|
|
|
|
assert.equal( $link.attr( 'title' ), 'link title', 'The link has a title on blur.' );
|
|
|
|
|
|
|
|
$link.data( 'dont-empty-title', true );
|
|
|
|
$link.trigger( 'mouseenter' );
|
|
|
|
assert.equal( $link.attr( 'title' ), 'link title',
|
|
|
|
'The link title is not removed when `dont-empty-title` data attribute is `true`.' );
|
|
|
|
|
|
|
|
$link.remove();
|
|
|
|
} );
|
|
|
|
|
|
|
|
QUnit.test( 'selectPopupElements', function ( assert ) {
|
|
|
|
var $originalContent = mw.popups.$content,
|
|
|
|
IGNORE_CLASSES = [
|
|
|
|
'.extiw',
|
|
|
|
'.image',
|
|
|
|
'.new',
|
|
|
|
'.internal',
|
|
|
|
'.external',
|
|
|
|
'.oo-ui-buttonedElement-button'
|
|
|
|
],
|
|
|
|
$cancelLink = $( '<span>', {
|
|
|
|
class: 'cancelLink'
|
|
|
|
} );
|
|
|
|
|
|
|
|
QUnit.expect( 1 );
|
|
|
|
|
|
|
|
mw.popups.$content = $( '<div>' );
|
|
|
|
|
|
|
|
// add links that we know will be ignored
|
|
|
|
$.each( IGNORE_CLASSES, function ( i, className ) {
|
|
|
|
$( '<a>', {
|
|
|
|
text: 'link with tooltip',
|
|
|
|
title: 'link title',
|
|
|
|
class: className.substring( 1 ),
|
|
|
|
href: '/wiki/Popups'
|
|
|
|
} ).appendTo( mw.popups.$content );
|
|
|
|
} );
|
|
|
|
|
|
|
|
// add a link that's part of a .cancelLink
|
|
|
|
$( '<a>', {
|
|
|
|
text: 'link with tooltip',
|
|
|
|
title: 'link title',
|
|
|
|
href: '/wiki/Popups'
|
|
|
|
} ).appendTo( $cancelLink );
|
|
|
|
$cancelLink.appendTo( mw.popups.$content );
|
|
|
|
|
|
|
|
// add a link without `href`, which means the link doesn't point to a valid page
|
|
|
|
$( '<a>', {
|
|
|
|
text: 'link with tooltip',
|
|
|
|
title: 'link title'
|
|
|
|
} ).appendTo( mw.popups.$content );
|
|
|
|
|
2016-04-22 09:19:34 +00:00
|
|
|
// Add a link that's not in a content namespace.
|
|
|
|
$( '<a>', {
|
|
|
|
text: 'link with tooltip',
|
|
|
|
title: 'foo.jpg',
|
|
|
|
href: '/wiki/File:foo.jpg'
|
|
|
|
} ).appendTo( mw.popups.$content );
|
|
|
|
|
2016-04-13 21:21:38 +00:00
|
|
|
// add a link that will have a hover card
|
|
|
|
$( '<a>', {
|
|
|
|
text: 'link with tooltip',
|
|
|
|
title: 'link title',
|
|
|
|
href: '/wiki/Popups'
|
|
|
|
} ).appendTo( mw.popups.$content );
|
|
|
|
|
|
|
|
// only the last link above should be selected for having a hover card
|
|
|
|
assert.equal(
|
|
|
|
mw.popups.selectPopupElements().length,
|
|
|
|
1,
|
|
|
|
'Explicitly ignored links and links that do not have a `href` attribute are not considered for having a popup.' );
|
|
|
|
|
|
|
|
mw.popups.$content = $originalContent;
|
|
|
|
} );
|
|
|
|
|
2016-04-22 09:55:01 +00:00
|
|
|
QUnit.test( 'setupTriggers', function ( assert ) {
|
|
|
|
var $link = $( '<a>', {
|
|
|
|
text: 'Popups',
|
|
|
|
title: 'Popups',
|
|
|
|
href: '#'
|
|
|
|
} ).appendTo( 'body' ),
|
|
|
|
originalScrolled = mw.popups.scrolled,
|
|
|
|
renderSpy = this.sandbox.stub( mw.popups.render, 'render', $.noop ),
|
|
|
|
$renderedElement;
|
|
|
|
|
|
|
|
assert.expect( 1 );
|
|
|
|
|
|
|
|
mw.popups.setupTriggers( $link );
|
|
|
|
|
|
|
|
mw.popups.scrolled = false;
|
|
|
|
$link.trigger( 'mouseenter' );
|
|
|
|
|
|
|
|
$renderedElement = renderSpy.firstCall.args[ 0 ];
|
|
|
|
|
|
|
|
assert.strictEqual(
|
|
|
|
// Compare the underlying element rather than (likely) differing instances of the jQuery
|
|
|
|
// class.
|
|
|
|
$renderedElement.get( 0 ),
|
|
|
|
$link.get( 0 ),
|
|
|
|
'When the "mouseenter" event fires then the underlying element is passed to the renderer.'
|
|
|
|
);
|
|
|
|
|
|
|
|
// Restore original state.
|
|
|
|
mw.popups.scrolled = originalScrolled;
|
|
|
|
$link.remove();
|
|
|
|
} );
|
|
|
|
|
2016-05-12 22:37:19 +00:00
|
|
|
QUnit.test( 'getAction', function ( assert ) {
|
|
|
|
var i, expected, actual,
|
|
|
|
// 0 - main button, 1 - middle button
|
|
|
|
cases = [
|
|
|
|
[ { button: 0 }, 'opened in same tab' ],
|
|
|
|
[ { button: 0, ctrlKey: true }, 'opened in new tab' ],
|
|
|
|
[ { button: 0, metaKey: true }, 'opened in new tab' ],
|
|
|
|
[ { button: 0, ctrlKey: true, shiftKey: true }, 'opened in new tab' ],
|
|
|
|
[ { button: 0, metaKey: true, shiftKey: true }, 'opened in new tab' ],
|
|
|
|
[ { button: 0, ctrlKey: true, metaKey: true, shiftKey: true }, 'opened in new tab' ],
|
|
|
|
[ { button: 0, shiftKey: true }, 'opened in new window' ],
|
|
|
|
[ { button: 1 }, 'opened in new tab' ],
|
|
|
|
[ { button: 1, shiftKey: true }, 'opened in new tab' ]
|
|
|
|
];
|
|
|
|
|
|
|
|
QUnit.expect( cases.length );
|
|
|
|
|
|
|
|
for ( i = 0; i < cases.length; i++ ) {
|
|
|
|
expected = cases[ i ][ 1 ];
|
|
|
|
actual = mw.popups.getAction( new MouseEvent( 'CustomEvent', cases[ i ][ 0 ] ) );
|
|
|
|
assert.equal( actual, expected );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
|
2016-05-16 20:32:11 +00:00
|
|
|
QUnit.test( 'getRandomToken', function ( assert ) {
|
|
|
|
var token;
|
|
|
|
|
|
|
|
QUnit.expect( 3 );
|
|
|
|
|
|
|
|
token = mw.popups.getRandomToken();
|
|
|
|
assert.ok(
|
|
|
|
token.length > mw.user.generateRandomSessionId().length,
|
|
|
|
'Random token is long enough.'
|
|
|
|
);
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
typeof token === 'string',
|
|
|
|
'Random token is a string.'
|
|
|
|
);
|
|
|
|
|
|
|
|
assert.notEqual(
|
|
|
|
mw.popups.getRandomToken(),
|
|
|
|
token,
|
|
|
|
'Newly generated random token is not equal to the one generated earlier.'
|
|
|
|
);
|
|
|
|
} );
|
|
|
|
|
|
|
|
QUnit.test( 'getPreviewCountBucket', function ( assert ) {
|
|
|
|
var i, previewCount, bucket,
|
|
|
|
cases = [
|
|
|
|
[ '0', '0 previews' ],
|
|
|
|
[ '1', '1-4 previews' ],
|
|
|
|
[ '2', '1-4 previews' ],
|
|
|
|
[ '4', '1-4 previews' ],
|
|
|
|
[ '5', '5-20 previews' ],
|
|
|
|
[ '10', '5-20 previews' ],
|
|
|
|
[ '20', '5-20 previews' ],
|
|
|
|
[ '21', '21+ previews' ],
|
|
|
|
[ '100', '21+ previews' ],
|
|
|
|
[ '1000', '21+ previews' ]
|
|
|
|
],
|
|
|
|
storageKey = 'ext.popups.core.previewCount',
|
|
|
|
mwStorageStub = this.sandbox.stub( mw.storage, 'get' )
|
|
|
|
.withArgs( storageKey );
|
|
|
|
|
|
|
|
QUnit.expect( cases.length + 1 );
|
|
|
|
|
|
|
|
mwStorageStub.returns( false );
|
|
|
|
assert.equal(
|
|
|
|
mw.popups.getPreviewCountBucket(),
|
|
|
|
'unknown',
|
|
|
|
'Preview count bucket is `unkown` when localStorage is unsupported.'
|
|
|
|
);
|
|
|
|
|
|
|
|
for ( i = 0; i < cases.length; i++ ) {
|
|
|
|
previewCount = cases[ i ][ 0 ];
|
|
|
|
mwStorageStub.returns( previewCount );
|
|
|
|
bucket = mw.popups.getPreviewCountBucket();
|
|
|
|
assert.equal(
|
|
|
|
bucket,
|
|
|
|
cases[ i ][ 1 ],
|
|
|
|
'Preview count bucket is "' + bucket + '" when preview count is ' +
|
|
|
|
previewCount + '.'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
|
|
|
|
QUnit.test( 'incrementPreviewCount', function ( assert ) {
|
|
|
|
var storageKey = 'ext.popups.core.previewCount',
|
|
|
|
mwStorageGetStub = this.sandbox.stub( mw.storage, 'get' )
|
|
|
|
.withArgs( storageKey ),
|
|
|
|
mwStorageSetStub = this.sandbox.stub( mw.storage, 'set' );
|
|
|
|
|
|
|
|
QUnit.expect( 3 );
|
|
|
|
|
|
|
|
mwStorageGetStub.returns( null );
|
|
|
|
mw.popups.incrementPreviewCount();
|
|
|
|
assert.equal(
|
|
|
|
mwStorageSetStub.firstCall.args[ 1 ],
|
|
|
|
1,
|
|
|
|
'Incrementing the preview count to 1 when no value has' +
|
|
|
|
' been saved in localStorage yet.'
|
|
|
|
);
|
|
|
|
|
|
|
|
mwStorageGetStub.returns( '1' );
|
|
|
|
mw.popups.incrementPreviewCount();
|
|
|
|
assert.equal(
|
|
|
|
mwStorageSetStub.secondCall.args[ 1 ],
|
|
|
|
2,
|
|
|
|
'Incrementing the preview count to 2 when the value in localStorage' +
|
|
|
|
' is already "1".'
|
|
|
|
);
|
|
|
|
|
|
|
|
mwStorageGetStub.returns( '5' );
|
|
|
|
mw.popups.incrementPreviewCount();
|
|
|
|
assert.equal(
|
|
|
|
mwStorageSetStub.thirdCall.args[ 1 ],
|
|
|
|
6,
|
|
|
|
'Incrementing the preview count to 6 when the value in localStorage' +
|
|
|
|
' is already "5".'
|
|
|
|
);
|
|
|
|
} );
|
|
|
|
|
|
|
|
QUnit.test( 'saveEnabledState', function ( assert ) {
|
|
|
|
var storageKey = 'mwe-popups-enabled',
|
2016-05-13 20:15:36 +00:00
|
|
|
deviceStorageStub = this.sandbox.stub( mw.storage, 'set' )
|
2016-05-16 20:32:11 +00:00
|
|
|
.withArgs( storageKey );
|
|
|
|
|
|
|
|
QUnit.expect( 2 );
|
|
|
|
|
|
|
|
mw.popups.saveEnabledState( true );
|
|
|
|
assert.equal(
|
2016-05-13 20:15:36 +00:00
|
|
|
deviceStorageStub.firstCall.args[ 1 ],
|
|
|
|
'1',
|
2016-05-16 20:32:11 +00:00
|
|
|
'Popups enabled state has been saved as "true".'
|
|
|
|
);
|
|
|
|
|
|
|
|
mw.popups.saveEnabledState( false );
|
|
|
|
assert.equal(
|
2016-05-13 20:15:36 +00:00
|
|
|
deviceStorageStub.secondCall.args[ 1 ],
|
|
|
|
'0',
|
2016-05-16 20:32:11 +00:00
|
|
|
'Popups enabled state has been saved as "false".'
|
|
|
|
);
|
|
|
|
} );
|
|
|
|
|
|
|
|
QUnit.test( 'getEnabledState', function ( assert ) {
|
|
|
|
var storageKey = 'mwe-popups-enabled',
|
|
|
|
mwConfigStub = this.sandbox.stub( mw.config, 'get' )
|
|
|
|
.withArgs( 'wgPopupsExperiment' ),
|
2016-05-13 20:15:36 +00:00
|
|
|
deviceStorageStub = this.sandbox.stub( mw.storage, 'get' )
|
2016-05-16 20:32:11 +00:00
|
|
|
.withArgs( storageKey ),
|
|
|
|
experimentStub = this.sandbox.stub( mw.popups.experiment,
|
|
|
|
'isUserInCondition' );
|
|
|
|
|
|
|
|
QUnit.expect( 7 );
|
|
|
|
|
|
|
|
mwConfigStub.returns( null );
|
2016-05-13 20:15:36 +00:00
|
|
|
deviceStorageStub.returns( null );
|
2016-05-16 20:32:11 +00:00
|
|
|
assert.equal(
|
|
|
|
mw.popups.getEnabledState(),
|
|
|
|
true,
|
|
|
|
'Popups are enabled when the experiment is not running, nor has' +
|
|
|
|
' Popups been disabled via the settings.'
|
|
|
|
);
|
|
|
|
|
|
|
|
mwConfigStub.returns( null );
|
2016-05-13 20:15:36 +00:00
|
|
|
deviceStorageStub.returns( '1' );
|
2016-05-16 20:32:11 +00:00
|
|
|
assert.equal(
|
|
|
|
mw.popups.getEnabledState(),
|
|
|
|
true,
|
|
|
|
'Popups are enabled when the experiment is not running and when' +
|
|
|
|
' Popups has been enabled via the settings.'
|
|
|
|
);
|
|
|
|
|
|
|
|
mwConfigStub.returns( null );
|
2016-05-13 20:15:36 +00:00
|
|
|
deviceStorageStub.returns( '0' );
|
2016-05-16 20:32:11 +00:00
|
|
|
assert.equal(
|
|
|
|
mw.popups.getEnabledState(),
|
|
|
|
false,
|
|
|
|
'Popups are disabled when the experiment is not running and when' +
|
|
|
|
' Popups has been disabled via the settings.'
|
|
|
|
);
|
|
|
|
|
|
|
|
mwConfigStub.returns( false );
|
2016-05-13 20:15:36 +00:00
|
|
|
deviceStorageStub.returns( '1' );
|
2016-05-16 20:32:11 +00:00
|
|
|
assert.equal(
|
|
|
|
mw.popups.getEnabledState(),
|
|
|
|
true,
|
|
|
|
'Popups are enabled when the experiment is disabled and when' +
|
|
|
|
' Popups has been enabled via the settings.'
|
|
|
|
);
|
|
|
|
|
|
|
|
mwConfigStub.returns( false );
|
2016-05-13 20:15:36 +00:00
|
|
|
deviceStorageStub.returns( '0' );
|
2016-05-16 20:32:11 +00:00
|
|
|
assert.equal(
|
|
|
|
mw.popups.getEnabledState(),
|
|
|
|
false,
|
|
|
|
'Popups are disabled when the experiment is disabled and when' +
|
|
|
|
' Popups has been disabled via the settings.'
|
|
|
|
);
|
|
|
|
|
|
|
|
mwConfigStub.returns( true );
|
|
|
|
experimentStub.returns( true );
|
|
|
|
assert.equal(
|
|
|
|
mw.popups.getEnabledState(),
|
|
|
|
true,
|
|
|
|
'Popups are disabled when the experiment is running and ' +
|
|
|
|
' the user is bucketed.'
|
|
|
|
);
|
|
|
|
|
|
|
|
mwConfigStub.returns( true );
|
|
|
|
experimentStub.returns( false );
|
|
|
|
assert.equal(
|
|
|
|
mw.popups.getEnabledState(),
|
|
|
|
false,
|
|
|
|
'Popups are disabled when the experiment is running and ' +
|
|
|
|
' the user is not bucketed.'
|
|
|
|
);
|
|
|
|
} );
|
2015-08-26 10:15:16 +00:00
|
|
|
} )( jQuery, mediaWiki );
|