// Notifications center: entries from chat and announcements, counting, reading, clearing. const http = require('http'), assert = require('assert'), fs = require('fs'), os = require('os'), path = require('path'); process.env.DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'nehub-inbox-')); const users = require('../users'), inbox = require('../inbox'), chat = require('../chat'); const P = { a: users.create({ name: 'Ann', role: 'admin', handle: 'YQ' }), b: users.create({ name: 'Bob', role: 'user', tabs: ['chat'], handle: 'Yg' }) }; const hub = http.createServer((req, res) => users.runAs(P[req.headers['x-user'] || 'a'], () => req.url.startsWith('/api/chat') ? chat.handle(req, res) : inbox.handle(req, res))).listen(0, async () => { const B = 'http://127.0.0.1:' + hub.address().port, call = (p, o = {}, who) => fetch(B + p, { ...o, headers: { ...(o.headers || {}), ...(who ? { 'x-user': who } : {}) } }), post = (p, b, who) => call(p, { method: 'POST', body: JSON.stringify(b) }, who), j = r => r.json(); try { const dm = (await j(await post('/api/chat/new', { type: 'direct', with: P.b.id }, 'a'))).conv; await post('/api/chat/send', { conv: dm.id, text: 'hello' }, 'a'); await post('/api/chat/send', { conv: dm.id, text: 'again' }, 'a'); let r = await j(await call('/api/inbox', {}, 'b')); assert.equal(r.items.length, 1, 'one entry per conversation'); assert.equal(r.items[0].count, 2); assert.equal(r.items[0].body, 'again'); assert.equal(r.unread, 1); assert.equal((await j(await call('/api/inbox', {}, 'a'))).items.length, 0, 'the sender gets nothing'); await post('/api/chat/announcement', { text: 'Pizza night' }, 'a'); r = await j(await call('/api/inbox', {}, 'b')); assert.equal(r.items[0].kind, 'announce'); assert.equal(r.unread, 2); r = await j(await post('/api/inbox/read', { id: r.items[0].id }, 'b')); assert.equal(r.unread, 1); await post('/api/chat/send', { conv: dm.id, text: 'new one' }, 'a'); r = await j(await call('/api/inbox', {}, 'b')); assert.equal(r.items.filter(i => i.kind === 'chat').length, 1, 'still unread: updated in place'); assert.equal(r.items.find(i => i.kind === 'chat').count, 3); r = await j(await post('/api/inbox/read', { all: true }, 'b')); assert.equal(r.unread, 0); await post('/api/chat/send', { conv: dm.id, text: 'after reading' }, 'a'); r = await j(await call('/api/inbox', {}, 'b')); assert.equal(r.items.filter(i => i.kind === 'chat').length, 2, 'a read entry stays; a new one starts'); await post('/api/inbox/clear', {}, 'b'); assert.equal((await j(await call('/api/inbox', {}, 'b'))).items.length, 0); console.log('inbox ok'); } catch (e) { console.error(e); process.exitCode = 1; } hub.close(); setTimeout(() => process.exit(process.exitCode || 0), 50); });