tests: Fix QUnit warnings and resolve complex test_NotificationBadge
== Problem 1 ==
As of I09c27a084100b223, tests/qunit/index.js or equiv was used to
load test files asynchronously from a using() callback. This was
untracked by RL or QUnit, and thus sometimes ended up finishing after
the test runner was already done executing all tests. In CI this
means the tests are sometimes never loaded and the browser (or Node)
process already killed before they even have a chance to arrive.
Prior to QUnit 2.17, this was no way of detecting this. As of
QUnit 2.17 (core upgraded last week) when running tests manually
the following helpful warnings appear in the console:
> [warning] Unexpected test after runEnd.
> [warning] This is unstable and will fail in QUnit 3.0.
> test @ qunit.js
> tests/qunit/model/test_mw.echo.dm.SeenTimeModel.js
> require
There were about 1072 instances of this warning, all from Echo.
Fix this problem by removing the async callbacks and specifying the
two modules as normal dependencies instead.
== Problem 2 ==
Class NotificationBadge was being loaded in a strange way out of
bound. This was a violation of module boundaries and should not be
needed other than for a temporary hack or other tech debt. More
generally when a test uses `packageFiles` this is a likely sign of
tech debt or misunderstandings.
Instead, depend on `ext.echo.mobile` and export/import the class
as normal.
After this, the test module can use `scripts` instead.
== Problem 3 ==
The `ext.echo.mobile` uses a Mustache template which the test
was also duplicating a reference to. This is no longer needed now.
Due to the `qunit/index.js` file carefully splitting the operations
between template assignment and file loading, I wondered whether
it was meaning to replace or mock it with something else, but it
simply refers to the same file and only does this because it wasn't
using the module directly. This is now resolved.
If you do need to mock in the future, this can simply be done
by assigning `NotificationBadge.prototype.template` from a
beforeEach() callback in the test suite, or by supporting it
property as a constructor option in NotificationBadge.js and
assigning `this.template` there, which is supported by the
mobile `View` class already it seems and would follow DI patterns
more effectively.
== Problem 4 ==
Most of the Echo tests were ignored sometimes and executed other
times.
The test for `ext.echo.mobile` in particular though was never
executed in CI specifically because:
> Undefined module: 'mobile.startup'
This became a hard error with this patch, which is fixed by
the CI config change with Ie9dabe3269c56fa76db8e51.
Bug: T299780
Change-Id: Ie4a87f3b8085fd6ae53ec586c1782cc266d5288a
2022-03-01 23:16:33 +00:00
|
|
|
var NotificationBadge = require( './NotificationBadge.js' );
|
|
|
|
|
2019-10-01 20:15:25 +00:00
|
|
|
var NOTIFICATIONS_PATH = '/notifications';
|
|
|
|
|
|
|
|
/**
|
2020-06-12 22:13:31 +00:00
|
|
|
* @fires echo.mobile every time the notifications overlay is opened
|
2019-10-01 20:15:25 +00:00
|
|
|
*/
|
|
|
|
function onOpenNotificationsOverlay() {
|
|
|
|
mw.hook( 'echo.mobile' ).fire( true );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-06-12 22:13:31 +00:00
|
|
|
* @fires echo.mobile every time the notifications overlay is closed
|
2019-10-01 20:15:25 +00:00
|
|
|
*/
|
|
|
|
function onCloseNotificationsOverlay() {
|
|
|
|
mw.hook( 'echo.mobile' ).fire( false );
|
|
|
|
}
|
|
|
|
|
2022-03-01 23:04:53 +00:00
|
|
|
/**
|
2019-10-01 20:15:25 +00:00
|
|
|
* This code loads the necessary modules for the notifications overlay, not to be confused
|
|
|
|
* with the Toast notifications defined by common/toast.js.
|
|
|
|
*/
|
2022-03-01 23:04:53 +00:00
|
|
|
function init() {
|
2019-10-01 20:15:25 +00:00
|
|
|
var badge,
|
|
|
|
notificationsFilterOverlay = require( './notificationsFilterOverlay.js' ),
|
|
|
|
notificationsOverlay = require( './overlay.js' ),
|
|
|
|
router = require( 'mediawiki.router' ),
|
|
|
|
overlayManager = mw.mobileFrontend.require( 'mobile.startup' ).OverlayManager.getSingleton(),
|
|
|
|
initialized = false;
|
|
|
|
|
|
|
|
function showNotificationOverlay() {
|
|
|
|
var overlay = notificationsOverlay( badge.setCount.bind( badge ),
|
|
|
|
badge.markAsSeen.bind( badge ), function ( exit ) {
|
|
|
|
onCloseNotificationsOverlay();
|
|
|
|
exit();
|
|
|
|
} );
|
|
|
|
onOpenNotificationsOverlay();
|
|
|
|
|
|
|
|
return overlay;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Once the DOM is loaded hijack the notifications button to display an overlay rather
|
|
|
|
// than linking to Special:Notifications.
|
|
|
|
$( function () {
|
|
|
|
badge = new NotificationBadge( {
|
|
|
|
onClick: function ( ev ) {
|
|
|
|
router.navigate( '#' + NOTIFICATIONS_PATH );
|
|
|
|
// prevent navigation to original Special:Notifications URL
|
|
|
|
// DO NOT USE stopPropagation or you'll break click tracking in WikimediaEvents
|
|
|
|
ev.preventDefault();
|
|
|
|
},
|
|
|
|
// eslint-disable-next-line no-jquery/no-global-selector
|
2022-02-08 17:14:46 +00:00
|
|
|
el: $( '.minerva-user-notifications ul' ).parent()
|
2019-10-01 20:15:25 +00:00
|
|
|
} );
|
|
|
|
overlayManager.add( /^\/notifications$/, showNotificationOverlay );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds a filter button to the UI inside notificationsInboxWidget
|
2020-06-12 22:13:31 +00:00
|
|
|
*
|
2019-10-01 20:15:25 +00:00
|
|
|
* @method
|
|
|
|
* @ignore
|
|
|
|
*/
|
|
|
|
function addFilterButton() {
|
|
|
|
// Create filter button once the notifications overlay has been loaded
|
|
|
|
var filterStatusButton = new OO.ui.ButtonWidget(
|
|
|
|
{
|
|
|
|
href: '#/notifications-filter',
|
|
|
|
classes: [ 'mw-echo-ui-notificationsInboxWidget-main-toolbar-nav-filter-placeholder' ],
|
|
|
|
icon: 'funnel',
|
|
|
|
label: mw.msg( 'echo-mobile-notifications-filter-title' )
|
|
|
|
} );
|
|
|
|
|
|
|
|
// eslint-disable-next-line no-jquery/no-global-selector
|
|
|
|
$( '.mw-echo-ui-notificationsInboxWidget-cell-placeholder' ).append(
|
|
|
|
$( '<div>' )
|
|
|
|
.addClass( 'mw-echo-ui-notificationsInboxWidget-main-toolbar-nav-filter' )
|
|
|
|
.addClass( 'mw-echo-ui-notificationsInboxWidget-cell' )
|
|
|
|
.append( filterStatusButton.$element )
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
// This code will currently only be invoked on Special:Notifications
|
|
|
|
// The code is bundled here since it makes use of loadModuleScript. This also allows
|
|
|
|
// the possibility of invoking the filter from outside the Special page in future.
|
|
|
|
// Once the 'ext.echo.special.onInitialize' hook has fired, load notification filter.
|
|
|
|
mw.hook( 'ext.echo.special.onInitialize' ).add( function () {
|
|
|
|
// eslint-disable-next-line no-jquery/no-global-selector
|
|
|
|
var $crossWikiUnreadFilter = $( '.mw-echo-ui-crossWikiUnreadFilterWidget' ),
|
|
|
|
// eslint-disable-next-line no-jquery/no-global-selector
|
|
|
|
$notifReadState = $( '.mw-echo-ui-notificationsInboxWidget-main-toolbar-readState' );
|
|
|
|
|
|
|
|
// The 'ext.echo.special.onInitialize' hook is fired whenever special page notification
|
|
|
|
// changes display on click of a filter.
|
|
|
|
// Hence the hook is restricted from firing more than once.
|
|
|
|
if ( initialized ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// setup the filter button (now we have OOjs UI)
|
|
|
|
addFilterButton();
|
|
|
|
|
|
|
|
// setup route
|
|
|
|
overlayManager.add( /^\/notifications-filter$/, function () {
|
|
|
|
onOpenNotificationsOverlay();
|
|
|
|
return notificationsFilterOverlay( {
|
|
|
|
onBeforeExit: function ( exit ) {
|
|
|
|
onCloseNotificationsOverlay();
|
|
|
|
exit();
|
|
|
|
},
|
|
|
|
$notifReadState: $notifReadState,
|
|
|
|
$crossWikiUnreadFilter: $crossWikiUnreadFilter
|
|
|
|
} );
|
|
|
|
} );
|
|
|
|
initialized = true;
|
|
|
|
} );
|
|
|
|
} );
|
|
|
|
|
2022-03-01 23:04:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
module.exports.init = init;
|
tests: Fix QUnit warnings and resolve complex test_NotificationBadge
== Problem 1 ==
As of I09c27a084100b223, tests/qunit/index.js or equiv was used to
load test files asynchronously from a using() callback. This was
untracked by RL or QUnit, and thus sometimes ended up finishing after
the test runner was already done executing all tests. In CI this
means the tests are sometimes never loaded and the browser (or Node)
process already killed before they even have a chance to arrive.
Prior to QUnit 2.17, this was no way of detecting this. As of
QUnit 2.17 (core upgraded last week) when running tests manually
the following helpful warnings appear in the console:
> [warning] Unexpected test after runEnd.
> [warning] This is unstable and will fail in QUnit 3.0.
> test @ qunit.js
> tests/qunit/model/test_mw.echo.dm.SeenTimeModel.js
> require
There were about 1072 instances of this warning, all from Echo.
Fix this problem by removing the async callbacks and specifying the
two modules as normal dependencies instead.
== Problem 2 ==
Class NotificationBadge was being loaded in a strange way out of
bound. This was a violation of module boundaries and should not be
needed other than for a temporary hack or other tech debt. More
generally when a test uses `packageFiles` this is a likely sign of
tech debt or misunderstandings.
Instead, depend on `ext.echo.mobile` and export/import the class
as normal.
After this, the test module can use `scripts` instead.
== Problem 3 ==
The `ext.echo.mobile` uses a Mustache template which the test
was also duplicating a reference to. This is no longer needed now.
Due to the `qunit/index.js` file carefully splitting the operations
between template assignment and file loading, I wondered whether
it was meaning to replace or mock it with something else, but it
simply refers to the same file and only does this because it wasn't
using the module directly. This is now resolved.
If you do need to mock in the future, this can simply be done
by assigning `NotificationBadge.prototype.template` from a
beforeEach() callback in the test suite, or by supporting it
property as a constructor option in NotificationBadge.js and
assigning `this.template` there, which is supported by the
mobile `View` class already it seems and would follow DI patterns
more effectively.
== Problem 4 ==
Most of the Echo tests were ignored sometimes and executed other
times.
The test for `ext.echo.mobile` in particular though was never
executed in CI specifically because:
> Undefined module: 'mobile.startup'
This became a hard error with this patch, which is fixed by
the CI config change with Ie9dabe3269c56fa76db8e51.
Bug: T299780
Change-Id: Ie4a87f3b8085fd6ae53ec586c1782cc266d5288a
2022-03-01 23:16:33 +00:00
|
|
|
module.exports.NotificationBadge = NotificationBadge;
|