UNPKG

linagora-rse

Version:
949 lines (796 loc) 29 kB
'use strict'; var expect = require('chai').expect; var mockery = require('mockery'); var q = require('q'); describe('The daily digest core module', function() { var deps = {}; var dependencies = function(name) { return deps[name]; }; var tracker = { getTracker: function() {} }; var activitystreams = { tracker: tracker }; var helpers = { array: require('../../../../../backend/helpers/array') }; function initDependencies() { deps = { collaboration: {}, message: {}, user: {}, activitystreams: activitystreams, helpers: helpers, logger: { error: function() {}, info: function() {}, warning: function() {} } }; } beforeEach(function() { initDependencies(); }); describe('The digest fn', function() { describe('The userModule call', function() { it('should reject if user list fails', function() { deps.user.list = function(callback) { return callback(new Error()); }; var module = require('../../../lib/daily')(dependencies); return expect(module.digest()).to.be.rejected; }); it('should send back empty array if user list returns empty array', function() { var users = []; deps.user.list = function(callback) { return callback(null, users); }; var module = require('../../../lib/daily')(dependencies); return expect(module.digest()).to.become(users); }); it('should send back empty array if user list returns undefined', function() { deps.user.list = function(callback) { return callback(); }; var module = require('../../../lib/daily')(dependencies); return expect(module.digest()).to.become([]); }); }); describe('when users are available', function() { it('should call userDailyDigest as many time as there are users', function() { var users = [{ _id: '1', populate: function(path, callback) { return callback(null, {_id: '1'}); } }, { _id: '2', populate: function(path, callback) { return callback(null, {_id: '2'}); } }, { _id: '3', populate: function(path, callback) { return callback(null, {_id: '3'}); } }]; deps.user.list = function(callback) { return callback(null, users); }; var called = 0; var module = require('../../../lib/daily')(dependencies); module.userDailyDigest = function(user) { called++; return q(user); }; return module.digest().then(function() { expect(called).to.equal(users.length); }); }); it('should call userDailyDigest with user object with domain populated', function() { var called1 = 0; var called2 = 0; var called3 = 0; var users = [{ _id: '1', populate: function(path, callback) { expect(path).to.deep.equal('domains.domain_id'); called1++; return callback(null, {_id: '1'}); } }, { _id: '2', populate: function(path, callback) { expect(path).to.deep.equal('domains.domain_id'); called2++; return callback(null, {_id: '2'}); } }, { _id: '3', populate: function(path, callback) { expect(path).to.deep.equal('domains.domain_id'); called3++; return callback(null, {_id: '3'}); } }]; deps.user.list = function(callback) { return callback(null, users); }; var module = require('../../../lib/daily')(dependencies); module.userDailyDigest = function(user) { return q(user); }; return module.digest().then(function() { expect(called1).to.equal(1); expect(called2).to.equal(1); expect(called3).to.equal(1); }); }); }); }); describe('The userDailyDigest function', function() { it('should reject when user is undefined', function() { var module = require('../../../lib/daily')(dependencies); return expect(module.userDailyDigest()).to.be.rejected; }); describe('when collaborationModule.getCollaborationsForTuple sends back', function() { var user = {_id: Number('1'), emails: ['anEmail'] }; it('error', function() { deps.collaboration = { getCollaborationsForTuple: function(tuple, callback) { return callback(new Error()); } }; var module = require('../../../lib/daily')(dependencies); return expect(module.userDailyDigest(user)).to.be.rejected; }); it('undefined collaborations', function() { deps.collaboration = { getCollaborationsForTuple: function(tuple, callback) { return callback(); } }; var module = require('../../../lib/daily')(dependencies); return module.userDailyDigest(user).then(function(result) { expect(result.data).to.have.length(0); expect(result.status).to.match(/No collaborations found/); }); }); it('empty collaborations', function() { deps.collaboration = { getCollaborationsForTuple: function(tuple, callback) { return callback(null, []); } }; var module = require('../../../lib/daily')(dependencies); module.userDailyDigest(user).then(function(result) { expect(result.data).to.have.length(0); expect(result.status).to.match(/No collaborations found/); }); }); describe('collaboration list', function() { it('should call loadUserDataForCollaboration as many times as there are collaborations', function() { var collaborations = [1, 2, 3, 4]; var called = 0; deps.collaboration = { getCollaborationsForTuple: function(tuple, callback) { return callback(null, collaborations); } }; mockery.registerMock('./weight', function() { return { compute: function() { return q({}); } }; }); mockery.registerMock('./mail', function() { return { process: function() { return q({}); } }; }); mockery.registerMock('./tracker', function() { return { updateTracker: function() { return q({}); } }; }); var module = require('../../../lib/daily')(dependencies); var loadUserDataForCollaboration = function(u, c) { expect(u).to.deep.equal(user); called++; return q({messages: [], collaboration: c}); }; module.loadUserDataForCollaboration = loadUserDataForCollaboration; return module.userDailyDigest(user).then(function(result) { expect(result.status).to.not.exist; expect(called).to.equal(collaborations.length); }); }); it('should send email if there is at least one message returns by loadUserDataForCollaboration', function() { var collaborations = [1, 2, 3, 4]; var called = 0; deps.collaboration = { getCollaborationsForTuple: function(tuple, callback) { return callback(null, collaborations); } }; mockery.registerMock('./weight', function() { return { compute: function(user, data) { return q(data); } }; }); mockery.registerMock('./mail', function() { return { process: function() { called++; return q({}); } }; }); mockery.registerMock('./tracker', function() { return { updateTracker: function() { return q({}); } }; }); var module = require('../../../lib/daily')(dependencies); var loadUserDataForCollaboration = function(user, collaboration) { if (collaboration === collaborations[0]) { return q({messages: [{}], collaboration: collaboration}); } else { return q({messages: [], collaboration: collaboration}); } }; module.loadUserDataForCollaboration = loadUserDataForCollaboration; return module.userDailyDigest(user).then(function(result) { expect(result.status).to.not.exist; expect(called).to.equal(1); }); }); it('should NOT send email if there is no message returns by loadUserDataForCollaboration', function() { var collaborations = [1, 2, 3, 4]; var called = 0; deps.collaboration = { getCollaborationsForTuple: function(tuple, callback) { return callback(null, collaborations); } }; mockery.registerMock('./weight', function() { return { compute: function(user, data) { return q(data); } }; }); mockery.registerMock('./mail', function() { return { process: function() { called++; return q({}); } }; }); mockery.registerMock('./tracker', function() { return { updateTracker: function() { return q({}); } }; }); var module = require('../../../lib/daily')(dependencies); var loadUserDataForCollaboration = function(user, collaboration) { return q({messages: [], collaboration: collaboration}); }; module.loadUserDataForCollaboration = loadUserDataForCollaboration; return module.userDailyDigest(user).then(function(result) { expect(result.status).to.not.exist; expect(called).to.equal(0); }); }); }); }); }); describe('The loadUserDataForCollaboration function', function() { it('should reject when user is undefined', function() { var module = require('../../../lib/daily')(dependencies); return expect(module.loadUserDataForCollaboration(null, {})).to.be.rejected; }); it('should reject when collaboration is undefined', function() { var module = require('../../../lib/daily')(dependencies); return expect(module.loadUserDataForCollaboration({}, null)).to.be.rejected; }); describe('When getting tracker', function() { it('should reject when getTracker sends back error', function() { var module = require('../../../lib/daily')(dependencies); var getTracker = function() { return q.reject(new Error()); }; module.getTracker = getTracker; return expect(module.loadUserDataForCollaboration({}, {})).to.be.rejected; }); }); describe('when loading thread', function() { var user = {_id: 1}; var collaboration = { activity_stream: { uuid: 123 } }; it('should reject when buildThreadViewSinceLastTimelineEntry sends back error', function() { var tracker = { buildThreadViewSinceLastTimelineEntry: function(userId, uuid, callback) { return callback(new Error()); } }; var module = require('../../../lib/daily')(dependencies); var getTracker = function() { return q(tracker); }; module.getTracker = getTracker; return expect(module.loadUserDataForCollaboration(user, collaboration)).to.be.rejected; }); it('should resolve when buildThreadViewSinceLastTimelineEntry sends back empty thread', function() { var tracker = { buildThreadViewSinceLastTimelineEntry: function(userId, uuid, callback) { return callback(); } }; var module = require('../../../lib/daily')(dependencies); var getTracker = function() { return q(tracker); }; module.getTracker = getTracker; return expect(module.loadUserDataForCollaboration(user, collaboration)).to.become({ messages: [], collaboration: collaboration }); }); it('should call buildMessageContext as many times as there are threads', function() { var threads = {1: {}, 2: {}, 3: {}}; var call = 0; var tracker = { buildThreadViewSinceLastTimelineEntry: function(userId, uuid, callback) { return callback(null, threads); } }; var module = require('../../../lib/daily')(dependencies); var getTracker = function() { return q(tracker); }; module.getTracker = getTracker; var buildMessageContext = function() { call++; return q({}); }; module.buildMessageContext = buildMessageContext; return module.loadUserDataForCollaboration(user, collaboration, tracker) .then(function() { expect(call).to.equal(3); }); }); it('should return only message which have the involved field set to false', function() { var threads = {1: {}, 2: {}, 3: {}}; var call = 0; var tracker = { buildThreadViewSinceLastTimelineEntry: function(userId, uuid, callback) { return callback(null, threads); } }; var module = require('../../../lib/daily')(dependencies); var getTracker = function() { return q(tracker); }; module.getTracker = getTracker; var buildMessageContext = function() { call++; if (call === 2) { return q({involved: true}); } return q({involved: false}); }; module.buildMessageContext = buildMessageContext; return module.loadUserDataForCollaboration(user, collaboration, tracker) .then(function(data) { expect(call).to.equal(Object.keys(threads).length); expect(data.messages).to.have.length(2); data.messages.forEach(function(message) { expect(message.involved).to.be.false; }); }); }); it('should not return undefined, empty message or message with involved field set to undefined', function() { var threads = {1: {}, 2: {}, 3: {}, 4: {}}; var call = 0; var tracker = { buildThreadViewSinceLastTimelineEntry: function(userId, uuid, callback) { return callback(null, threads); } }; var module = require('../../../lib/daily')(dependencies); var getTracker = function() { return q(tracker); }; module.getTracker = getTracker; var buildMessageContext = function() { call++; if (call === 1) { return q({involved: false}); } else if (call === 2) { return q({}); } else if (call === 3) { return q(); } return q({involved: undefined}); }; module.buildMessageContext = buildMessageContext; return module.loadUserDataForCollaboration(user, collaboration, tracker) .then(function(data) { expect(call).to.equal(Object.keys(threads).length); expect(data.messages).to.have.length(1); data.messages.forEach(function(message) { expect(message.involved).to.be.false; }); }); }); }); }); describe('The buildMessageContext function', function() { var id = 123; var thread = { message: { _id: id } }; it('should reject when thread is undefined', function() { var module = require('../../../lib/daily')(dependencies); return expect(module.buildMessageContext()).to.be.rejected; }); it('should reject when user is undefined', function() { var module = require('../../../lib/daily')(dependencies); return expect(module.buildMessageContext({})).to.be.rejected; }); it('should resolve with message and thread when message#get is ok', function() { var message = {_id: 1, content: 'YOLO'}; deps.message = { get: function(id, callback) { return callback(null, message); } }; var module = require('../../../lib/daily')(dependencies); var setReadAndInvolvedFlags = function(message) { return q(message); }; module.setReadAndInvolvedFlags = setReadAndInvolvedFlags; return expect(module.buildMessageContext(thread, {})).to.become(message); }); it('should resolve with empty message and thread when message#get is ko', function() { deps.message = { get: function(id, callback) { return callback(new Error('KO')); } }; var module = require('../../../lib/daily')(dependencies); var setReadAndInvolvedFlags = function(message) { return q(message); }; module.setReadAndInvolvedFlags = setReadAndInvolvedFlags; return expect(module.buildMessageContext(thread, {})).to.become({}); }); }); describe('getTracker function', function() { it('should reject when user is undefined', function() { var module = require('../../../lib/daily')(dependencies); return expect(module.getTracker(null, {})).to.be.rejected; }); it('should reject when collaboration is undefined', function() { var module = require('../../../lib/daily')(dependencies); return expect(module.getTracker({})).to.be.rejected; }); it('should call getLastTimelineEntry on each tracker', function() { var read = 0; var push = 0; var lastRead = 1; var lastPush = 2; var trackers = { read: { getLastTimelineEntry: function(user, uuid, callback) { read++; return callback(null, lastRead); } }, push: { getLastTimelineEntry: function(user, uuid, callback) { push++; return callback(null, lastPush); } } }; deps.activitystreams.tracker = { getTracker: function(type) { return trackers[type]; } }; var getMostRecentTimelineEntry = function(id1) { return q(id1); }; var module = require('../../../lib/daily')(dependencies); module.getMostRecentTimelineEntry = getMostRecentTimelineEntry; return module.getTracker({_id: 1}, {activity_stream: {uuid: 2}}).then(function() { expect(read).to.equal(1); expect(push).to.equal(1); }); }); describe('When calling getMostRecentTimelineEntry', function() { var trackers = { read: { getLastTimelineEntry: function(user, uuid, callback) { return callback(null, 1); } }, push: { getLastTimelineEntry: function(user, uuid, callback) { return callback(null, 2); } } }; beforeEach(function() { deps.activitystreams.tracker = { getTracker: function(type) { return trackers[type]; } }; }); it('should resolve with read tracker when no result is returned from getMostRecentTimelineEntry', function() { var getMostRecentTimelineEntry = function() { return q(); }; var module = require('../../../lib/daily')(dependencies); module.getMostRecentTimelineEntry = getMostRecentTimelineEntry; return expect(module.getTracker({_id: 1}, {activity_stream: {uuid: 2}})).to.become(trackers.read); }); it('should resolve with read tracker when read is most recent than push', function() { var getMostRecentTimelineEntry = function(id1) { return q(id1); }; var module = require('../../../lib/daily')(dependencies); module.getMostRecentTimelineEntry = getMostRecentTimelineEntry; return expect(module.getTracker({_id: 1}, {activity_stream: {uuid: 2}})).to.become(trackers.read); }); it('should resolve with push tracker when push is most recent than read', function() { var getMostRecentTimelineEntry = function(id1, id2) { return q(id2); }; var module = require('../../../lib/daily')(dependencies); module.getMostRecentTimelineEntry = getMostRecentTimelineEntry; return expect(module.getTracker({_id: 1}, {activity_stream: {uuid: 2}})).to.become(trackers.push); }); }); }); describe('getMostRecentTimelineEntry function', function() { it('should resolve empty when timelineentries are null', function() { var module = require('../../../lib/daily')(dependencies); return expect(module.getMostRecentTimelineEntry()).to.become(undefined); }); it('should resolve with timelineEntryId1 when timelineEntryId2 is not defined', function() { var id = 1; var module = require('../../../lib/daily')(dependencies); return expect(module.getMostRecentTimelineEntry(id)).to.become(id); }); it('should resolve with timelineEntryId2 when timelineEntryId1 is not defined', function() { var id = 1; var module = require('../../../lib/daily')(dependencies); return expect(module.getMostRecentTimelineEntry(null, id)).to.become(id); }); it('should resolve with empty when timelinesEntries are not found', function() { var id1 = 1, id2 = 2; deps.activitystreams.getTimelineEntry = function(id, callback) { return callback(); }; var module = require('../../../lib/daily')(dependencies); return expect(module.getMostRecentTimelineEntry(id1, id2)).to.become(undefined); }); it('should resolve with timelineEntryId1 when getTimelineEntry does not return timelineEntryId2', function() { var id1 = 1, id2 = 2; deps.activitystreams.getTimelineEntry = function(id, callback) { if (id === id1) { return callback(null, {id: id}); } return callback(); }; var module = require('../../../lib/daily')(dependencies); return expect(module.getMostRecentTimelineEntry(id1, id2)).to.become(id1); }); it('should resolve with timelineEntryId2 when getTimelineEntry does not return timelineEntryId1', function() { var id1 = 1, id2 = 2; deps.activitystreams.getTimelineEntry = function(id, callback) { if (id === id2) { return callback(null, {id: id}); } return callback(); }; var module = require('../../../lib/daily')(dependencies); return expect(module.getMostRecentTimelineEntry(id1, id2)).to.become(id2); }); it('should resolve with timelineEntryId2 if published date is bigger than timelineEntryId1 one', function() { var id1 = 1, id2 = 2; var date = new Date(1000); var date2 = new Date(2000); var tl1 = { id: id1, published: date }; var tl2 = { id: id2, published: date2 }; deps.activitystreams.getTimelineEntry = function(id, callback) { if (id === id1) { return callback(null, tl1); } return callback(null, tl2); }; var module = require('../../../lib/daily')(dependencies); return expect(module.getMostRecentTimelineEntry(id1, id2)).to.become(id2); }); it('should resolve with timelineEntryId1 if published date is bigger than timelineEntryId2 one', function() { var id1 = 1, id2 = 2; var date = new Date(); var date2 = new Date(); date2.setSeconds(date.getSeconds() + 10); var tl2 = { id: id2, published: date }; var tl1 = { id: id1, published: date2 }; deps.activitystreams.getTimelineEntry = function(id, callback) { if (id === id1) { return callback(null, tl1); } return callback(null, tl2); }; var module = require('../../../lib/daily')(dependencies); return expect(module.getMostRecentTimelineEntry(id1, id2)).to.become(id1); }); }); describe('setReadAndInvolvedFlags function', function() { it('should set message read flag to the thread read flag', function() { var message = {}; var thread = {read: true}; var module = require('../../../lib/daily')(dependencies); return expect(module.setReadAndInvolvedFlags(message, thread)).to.become({ read: thread.read, involved: false }); }); it('should set message involved flag to true if the user id is equal to the author id', function() { var userId = '1'; var message = { author: {_id: userId, id: userId} }; var thread = {}; var user = {_id: userId, id: userId}; var module = require('../../../lib/daily')(dependencies); return expect(module.setReadAndInvolvedFlags(message, thread, user)).to.eventually.shallowDeepEqual({ involved: true }); }); it('should set message and responses read flag to true if the message it not in the thread object', function() { var message = { _id: '1', id: '1', responses: [{ _id: '2', id: '2' }, { _id: '3', id: '3' }] }; var thread = {}; var module = require('../../../lib/daily')(dependencies); return expect(module.setReadAndInvolvedFlags(message, thread)).to.eventually.shallowDeepEqual({ read: true, responses: [{ read: true }, { read: true }] }); }); it('should set message and responses read flag to the thread read flag message and responses', function() { var message = { _id: '1', id: '1', responses: [{ _id: '2', id: '2' }, { _id: '3', id: '3' }] }; var thread = { read: false, responses: [{ message: { _id: message.responses[0]._id, id: message.responses[0]._id }, read: false }, { message: { _id: message.responses[1]._id, id: message.responses[1]._id }, read: true }] }; var module = require('../../../lib/daily')(dependencies); return expect(module.setReadAndInvolvedFlags(message, thread)).to.eventually.shallowDeepEqual({ read: false, responses: [{ read: false }, { read: true }] }); }); it('should set message involved flag to true if a response have the same author id than the user', function() { var userId = 'userId'; var userId2 = 'userId2'; var message = { _id: '1', id: '1', author: {_id: userId, id: userId}, responses: [{ _id: '2', id: '2', author: {_id: userId2, id: userId2} }, { _id: '3', id: '3', author: {_id: userId, id: userId} }] }; var thread = {}; var user = {_id: userId2, id: userId2}; var module = require('../../../lib/daily')(dependencies); return expect(module.setReadAndInvolvedFlags(message, thread, user)).to.eventually.shallowDeepEqual({ involved: true }); }); it('should set message involved flag to false if no response have the same author id than the user', function() { var userId = 'userId'; var userId2 = 'userId2'; var message = { _id: '1', id: '1', author: {_id: userId, id: userId}, responses: [{ _id: '2', id: '2', author: {_id: userId, id: userId} }, { _id: '3', id: '3', author: {_id: userId, id: userId} }] }; var thread = {}; var user = {_id: userId2, id: userId2}; var module = require('../../../lib/daily')(dependencies); return expect(module.setReadAndInvolvedFlags(message, thread, user)).to.eventually.shallowDeepEqual({ involved: false }); }); }); });