QUnit.module( 'ext.echo.dm - NotificationsList' ); QUnit.test.each( 'Constructing the model', { 'Empty config': { config: {}, expected: {}, }, 'Prefilled data': { config: { title: 'Some title', name: 'local_demo', source: 'hewiki', sourceURL: 'http://he.wiki.local.wmftest.net:8080/wiki/$1', timestamp: '20160916171300', }, expected: { getTitle: 'Some title', getName: 'local_demo', getSource: 'hewiki', getSourceURL: 'http://he.wiki.local.wmftest.net:8080/wiki/$1', getTimestamp: '20160916171300', isForeign: true, }, }, }, ( assert, data ) => { const defaultValues = { getAllItemIds: [], getAllItemIdsByType: [], getTitle: '', getName: 'local', getSource: 'local', getSourceURL: '', getTimestamp: 0, getCount: 0, hasUnseen: false, isForeign: false, }; const expected = $.extend( true, {}, defaultValues, data.expected ); const model = new mw.echo.dm.NotificationsList( data.config ); for ( const method in expected ) { assert.deepEqual( // Run the method model[ method ](), // Expected value expected[ method ], // Message method, ); } } ); QUnit.test( 'Handling notification items', ( assert ) => { const model = new mw.echo.dm.NotificationsList( { timestamp: '200101010000' } ); const items = [ new mw.echo.dm.NotificationItem( 0, { type: 'alert', timestamp: '201609190000', read: false, seen: false } ), new mw.echo.dm.NotificationItem( 1, { type: 'message', timestamp: '201609190100', read: false, seen: true } ), new mw.echo.dm.NotificationItem( 2, { type: 'alert', timestamp: '201609190200', read: true, seen: true } ), new mw.echo.dm.NotificationItem( 3, { type: 'message', timestamp: '201609190300', read: true, seen: true } ), new mw.echo.dm.NotificationItem( 4, { type: 'alert', timestamp: '201609190400', read: true, seen: true } ), new mw.echo.dm.NotificationItem( 5, { type: 'message', timestamp: '201609190500', read: true, seen: false } ), ]; assert.strictEqual( model.getCount(), 0, 'Model list starts empty', ); assert.strictEqual( model.getTimestamp(), '200101010000', 'Model timestamp is its default', ); model.setItems( items ); assert.strictEqual( model.getCount(), 6, 'Item list setup', ); assert.strictEqual( model.getTimestamp(), '201609190100', 'Model timestamp is the latest unread item\'s timestamp', ); assert.deepEqual( model.getAllItemIds(), [ 1, 0, 5, 4, 3, 2 ], 'getAllItemIds (sorted)', ); assert.deepEqual( [ model.getAllItemIdsByType( 'alert' ), model.getAllItemIdsByType( 'message' ), ], [ [ 0, 4, 2 ], [ 1, 5, 3 ], ], 'getAllItemIdsByType (sorted)', ); assert.deepEqual( model.findByIds( [ 1, 2 ] ), [ items[ 1 ], items[ 2 ] ], 'findByIds', ); // Change item state (trigger resort) items[ 1 ].toggleRead( true ); items[ 3 ].toggleRead( false ); items[ 5 ].toggleSeen( true ); // Will not affect sorting order of the item assert.deepEqual( model.getAllItemIds(), [ 3, 0, 5, 4, 2, 1 ], 'getAllItemIds (re-sorted)', ); // Discard items model.discardItems( [ items[ 5 ], items[ 2 ] ] ); assert.deepEqual( model.getAllItemIds(), [ 3, 0, 4, 1 ], 'getAllItemIds (discarded items)', ); assert.deepEqual( [ model.getAllItemIdsByType( 'alert' ), model.getAllItemIdsByType( 'message' ), ], [ [ 0, 4 ], [ 3, 1 ], ], 'getAllItemIdsByType (discarded items)', ); } ); QUnit.test( 'Intercepting events', ( assert ) => { const model = new mw.echo.dm.NotificationsList(); const result = []; const items = [ new mw.echo.dm.NotificationItem( 0, { timestamp: '201609190000', read: false, seen: false } ), new mw.echo.dm.NotificationItem( 1, { timestamp: '201609190100', read: false, seen: true } ), new mw.echo.dm.NotificationItem( 2, { timestamp: '201609190200', read: true, seen: true } ), new mw.echo.dm.NotificationItem( 3, { timestamp: '201609190300', read: true, seen: true } ), new mw.echo.dm.NotificationItem( 4, { timestamp: '201609190400', read: true, seen: true } ), new mw.echo.dm.NotificationItem( 5, { timestamp: '201609190500', read: true, seen: true } ), ]; // Listen to events model .on( 'update', ( itms ) => { result.push( 'update:' + itms.length ); } ) .on( 'discard', ( item ) => { result.push( 'discard:' + item.getId() ); } ) .on( 'itemUpdate', ( item ) => { result.push( 'itemUpdate:' + item.getId() ); } ); // Set up and trigger events model .setItems( items ); // [ 'update:6' ] model.discardItems( items[ items.length - 1 ] ); // [ 'update:6', 'discard:5' ] items[ 0 ].toggleSeen( true ); // [ 'update:6', 'discard:5', 'itemUpdate:0' ] items[ 1 ].toggleRead( true ); // [ 'update:6', 'discard:5', 'itemUpdate:0', 'itemUpdate:1' ] assert.deepEqual( // Actual result, // Expected: [ 'update:6', 'discard:5', 'itemUpdate:0', 'itemUpdate:1' ], // Message 'Events emitted correctly', ); } );