mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Echo
synced 2024-12-02 11:26:26 +00:00
02530f19e1
This is especially important for combined notifications and notification lists from different sources; the model list should be sorted to reflect items by timestamp and unread status. Note: The dm.List and dm.SortedList now mirror the structures OO.EmitterList and OO.SortedEmitterList that are awaiting to be added for oojs in Ib94e4e4a49 and I3fd569691549 respectively. Once those are available, the dm.List and dm.SortedList can be removed, and the model can mixin OO.SortedEmitterList instead. Change-Id: I97e1ecbe5dccc478be527a94f037500f78f74b14
243 lines
7.1 KiB
JavaScript
243 lines
7.1 KiB
JavaScript
( function ( mw, $ ) {
|
|
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.dm.AbstractAPIHandler );
|
|
// Override api call
|
|
TestApiHandler.prototype.markItemRead = function () {
|
|
return $.Deferred().resolve( 0 );
|
|
};
|
|
|
|
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( new TestApiHandler(), {
|
|
type: 'alert',
|
|
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( new TestApiHandler(), {
|
|
type: 'alert',
|
|
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( new TestApiHandler(), {
|
|
type: 'alert',
|
|
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 apiHandler = new TestApiHandler(),
|
|
model = new mw.echo.dm.NotificationsModel( apiHandler, {
|
|
type: 'alert',
|
|
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 );
|