mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Echo
synced 2024-12-02 19:36:48 +00:00
876197b520
Some complexity is now gone. We didn't currently have a good justification for a the APIHandler factory: the apiHandler caller would have to specify (variable `foreign`) what kind of handler it would like to initiate anyway, so it might as well just inject the object (which makes the code easier to follow, decreases bugs risk because there are less code paths) This also gives the caller more control of the API handlers: registerForeignSources will now be able to do more. Now it can e.g. create 1 object that is shared for multiple wikis (to do lookups for multiple wikis at once) Also renamed addApiHandler to setApiHandler (it just sets the value it needs without checking if it already existed anyway) Change-Id: Ie1814c5bf1a1f0e5607033beb506df67f3585b24
257 lines
7.5 KiB
JavaScript
257 lines
7.5 KiB
JavaScript
( function ( mw, $ ) {
|
|
var echoApi,
|
|
mockCounter,
|
|
noop = function () {};
|
|
|
|
QUnit.module( 'ext.echo.dm mw.echo.dm.NotificationsModel' );
|
|
|
|
function runPreparation( model, testPrepare ) {
|
|
var j, jlen;
|
|
|
|
for ( j = 0, jlen = testPrepare.length; j < jlen; j++ ) {
|
|
model[ testPrepare[ j ].method ].apply( model, testPrepare[ j ].params );
|
|
}
|
|
}
|
|
|
|
// Helper method to get an array of item ids for testing
|
|
function getIdArray( arr ) {
|
|
return arr.map( function ( item ) {
|
|
return item.getId();
|
|
} );
|
|
}
|
|
|
|
// Set up a dummy API handler to avoid sending requests to the API during tests
|
|
function TestApiHandler() {
|
|
// Parent constructor
|
|
TestApiHandler.parent.call( this );
|
|
}
|
|
/* Setup */
|
|
OO.inheritClass( TestApiHandler, mw.echo.api.APIHandler );
|
|
// Override api call
|
|
TestApiHandler.prototype.markItemsRead = function () {
|
|
return $.Deferred().resolve( 0 );
|
|
};
|
|
|
|
mockCounter = { estimateChange: noop, update: noop };
|
|
|
|
// Create an Echo API instance
|
|
echoApi = new mw.echo.api.EchoApi();
|
|
// HACK: Reach into the EchoAPI to create a test handler
|
|
echoApi.network.setApiHandler( 'test', new TestApiHandler() );
|
|
|
|
QUnit.test( 'Adding notifications', function ( assert ) {
|
|
var initialItems = [
|
|
new mw.echo.dm.NotificationItem( 0, { timestamp: '20150828173000', read: false } ),
|
|
new mw.echo.dm.NotificationItem( 1, { timestamp: '20150828173100', read: false } ),
|
|
new mw.echo.dm.NotificationItem( 2, { timestamp: '20150828173200', read: false } )
|
|
],
|
|
cases = [
|
|
{
|
|
items: initialItems,
|
|
expected: [ 2, 1, 0 ],
|
|
msg: 'Inserting items in timestamp order.'
|
|
},
|
|
{
|
|
items: [
|
|
initialItems[ 0 ],
|
|
initialItems[ 1 ],
|
|
initialItems[ 2 ],
|
|
initialItems[ 0 ]
|
|
],
|
|
expected: [ 2, 1, 0 ],
|
|
msg: 'Reinserting an item to its rightful position.'
|
|
},
|
|
{
|
|
items: [
|
|
new mw.echo.dm.NotificationItem( 0, { timestamp: '20150828173000', read: false } ),
|
|
new mw.echo.dm.NotificationItem( 1, { timestamp: '20150828173100', read: false } ),
|
|
new mw.echo.dm.NotificationItem( 2, { timestamp: '20150828173200', read: false } )
|
|
],
|
|
run: [
|
|
{
|
|
item: 0,
|
|
method: 'setTimestamp',
|
|
args: [ '20150830173000' ] // Newer timestamp
|
|
}
|
|
],
|
|
expected: [ 0, 2, 1 ],
|
|
msg: 'Changing timestamp on an item.'
|
|
},
|
|
{
|
|
items: [
|
|
new mw.echo.dm.NotificationItem( 0, { timestamp: '20150828173000', read: false } ),
|
|
new mw.echo.dm.NotificationItem( 1, { timestamp: '20150828173100', read: false } ),
|
|
new mw.echo.dm.NotificationItem( 2, { timestamp: '20150828173200', read: false } )
|
|
],
|
|
run: [
|
|
{
|
|
item: 1,
|
|
method: 'toggleRead',
|
|
args: [ true ] // Item is read
|
|
}
|
|
],
|
|
expected: [ 2, 0, 1 ],
|
|
msg: 'Changing read status of an item.'
|
|
}
|
|
];
|
|
|
|
QUnit.expect( cases.length );
|
|
|
|
cases.forEach( function ( test ) {
|
|
var r, runCase, runItem,
|
|
model = new mw.echo.dm.NotificationsModel( echoApi, mockCounter, {
|
|
type: 'alert',
|
|
source: 'test',
|
|
limit: 25,
|
|
userLang: 'en'
|
|
} );
|
|
|
|
model.addItems( test.items );
|
|
|
|
if ( test.add ) {
|
|
model.addItems( test.add.items );
|
|
}
|
|
if ( test.run ) {
|
|
for ( r = 0; r < test.run.length; r++ ) {
|
|
runCase = test.run[ r ];
|
|
runItem = test.items[ runCase.item ];
|
|
runItem[ runCase.method ].apply( runItem, runCase.args );
|
|
}
|
|
}
|
|
|
|
assert.deepEqual( getIdArray( model.getItems() ), test.expected, test.msg );
|
|
}, this );
|
|
} );
|
|
|
|
QUnit.test( 'Deleting notifications', 2, function ( assert ) {
|
|
var model = new mw.echo.dm.NotificationsModel( echoApi, mockCounter, {
|
|
type: 'alert',
|
|
source: 'test',
|
|
limit: 25,
|
|
userLang: 'en'
|
|
} ),
|
|
items = [
|
|
new mw.echo.dm.NotificationItem( 1, { content: '1', timestamp: '20150828172900' } ),
|
|
new mw.echo.dm.NotificationItem( 2, { content: '2', timestamp: '20150828172900' } ),
|
|
new mw.echo.dm.NotificationItem( 3, { content: '3', timestamp: '20150828172900' } ),
|
|
new mw.echo.dm.NotificationItem( 4, { content: '4', timestamp: '20150828172900' } ),
|
|
new mw.echo.dm.NotificationItem( 5, { content: '5', timestamp: '20150828172900' } ),
|
|
new mw.echo.dm.NotificationItem( 6, { content: '6', timestamp: '20150828172900' } ),
|
|
new mw.echo.dm.NotificationItem( 7, { content: '7', timestamp: '20150828172900' } ),
|
|
new mw.echo.dm.NotificationItem( 8, { content: '8', timestamp: '20150828172900' } ),
|
|
new mw.echo.dm.NotificationItem( 9, { content: '9', timestamp: '20150828172900' } ),
|
|
new mw.echo.dm.NotificationItem( 10, { content: '10', timestamp: '20150828172900' } )
|
|
];
|
|
|
|
// Add initial notifications
|
|
model.addItems( items );
|
|
|
|
// Verify we have the correct number initially
|
|
assert.equal( model.getItemCount(), 10, 'Added initial number of notifications' );
|
|
|
|
// Remove notifications
|
|
model.removeItems( [ items[ 0 ], items[ 1 ], items[ 5 ] ] );
|
|
|
|
// Test
|
|
assert.equal( model.getItemCount(), 7, 'Successfully deleted notifications' );
|
|
} );
|
|
|
|
QUnit.test( 'Clearing notifications', function ( assert ) {
|
|
var i, ilen, model, actual, test,
|
|
cases = [
|
|
{
|
|
prepare: [
|
|
{
|
|
method: 'addItems',
|
|
params: [
|
|
[
|
|
new mw.echo.dm.NotificationItem( 1, {
|
|
content: '1',
|
|
timestamp: '20150828172900'
|
|
} ),
|
|
new mw.echo.dm.NotificationItem( 2, { content: '2', timestamp: '20150828172900' } )
|
|
]
|
|
]
|
|
},
|
|
{
|
|
method: 'clearItems'
|
|
}
|
|
],
|
|
run: {
|
|
method: 'getItemCount'
|
|
},
|
|
expect: 0,
|
|
message: 'Clearing notifications'
|
|
}
|
|
];
|
|
|
|
assert.expect( cases.length );
|
|
|
|
for ( i = 0, ilen = cases.length; i < ilen; i++ ) {
|
|
model = new mw.echo.dm.NotificationsModel( echoApi, mockCounter, {
|
|
type: 'alert',
|
|
source: 'test',
|
|
limit: 25,
|
|
userLang: 'en'
|
|
} );
|
|
|
|
test = cases[ i ];
|
|
|
|
// Run preparation
|
|
runPreparation( model, test.prepare );
|
|
|
|
// Test
|
|
actual = model[ test.run.method ].apply( model, cases[ i ].run.params );
|
|
assert.equal( actual, cases[ i ].expect, cases[ i ].message );
|
|
}
|
|
} );
|
|
|
|
QUnit.test( 'Changing read/unread status', function ( assert ) {
|
|
var i,
|
|
initialItems = [
|
|
new mw.echo.dm.NotificationItem( 0, { timestamp: '20150828173000', read: false } ),
|
|
new mw.echo.dm.NotificationItem( 1, { timestamp: '20150828173100', read: false } ),
|
|
new mw.echo.dm.NotificationItem( 2, { timestamp: '20150828173200', read: false } ),
|
|
new mw.echo.dm.NotificationItem( 3, { timestamp: '20150828173300', read: false } ),
|
|
// Notice that in item 4 the timestamp is earlier
|
|
new mw.echo.dm.NotificationItem( 4, { timestamp: '20150828172900', read: true } ),
|
|
new mw.echo.dm.NotificationItem( 5, { timestamp: '20150828173500', read: true } )
|
|
],
|
|
cases = [
|
|
{
|
|
items: initialItems,
|
|
expected: [ 3, 2, 1, 0, 5, 4 ],
|
|
msg: 'Items organized by read/unread groups'
|
|
},
|
|
{
|
|
items: initialItems,
|
|
markRead: [ initialItems[ 1 ], initialItems[ 3 ] ],
|
|
expected: [ 2, 0, 5, 3, 1, 4 ],
|
|
msg: 'Items marked as read are pushed to the end'
|
|
}
|
|
];
|
|
|
|
QUnit.expect( cases.length );
|
|
|
|
cases.forEach( function ( test ) {
|
|
var model = new mw.echo.dm.NotificationsModel( echoApi, mockCounter, {
|
|
type: 'alert',
|
|
source: 'test',
|
|
limit: 25,
|
|
userLang: 'en'
|
|
} );
|
|
|
|
model.addItems( test.items );
|
|
|
|
if ( test.markRead ) {
|
|
for ( i = 0; i < test.markRead.length; i++ ) {
|
|
test.markRead[ i ].toggleRead( true );
|
|
}
|
|
}
|
|
|
|
assert.deepEqual( getIdArray( model.getItems() ), test.expected, test.msg );
|
|
}, this );
|
|
} );
|
|
|
|
} )( mediaWiki, jQuery );
|