[FIX][ENTERPRISE] Presence micro service logic (#24724)

This commit is contained in:
Diego Sampaio 2022-03-07 18:03:57 -03:00 committed by GitHub
parent f00a6b09e2
commit 9071f4cf3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 268 additions and 4 deletions

View File

@ -23,5 +23,5 @@ Object.assign(
module.exports = {
...base, // see https://github.com/mochajs/mocha/issues/3916
exit: true,
spec: ['app/**/*.spec.ts', 'app/**/*.tests.js', 'app/**/*.tests.ts', 'server/**/*.tests.ts'],
spec: ['app/**/*.spec.ts', 'app/**/*.tests.js', 'app/**/*.tests.ts', 'server/**/*.tests.ts', 'ee/**/*.tests.ts'],
};

View File

@ -26,8 +26,11 @@ export async function updateUserPresence(uid: string): Promise<void> {
}
const userSessions = (await UserSession.findOne(query)) || { connections: [] };
const { statusDefault = UserStatus.OFFLINE } = user;
const { status, statusConnection } = processPresenceAndStatus(userSessions.connections, statusDefault);
const result = await User.updateOne(query, {
$set: { status, statusConnection },
});

View File

@ -0,0 +1,241 @@
/* eslint-disable @typescript-eslint/camelcase */
import { expect } from 'chai';
import { UserStatus } from '../../../../../definition/UserStatus';
import { processConnectionStatus, processStatus, processPresenceAndStatus } from './processConnectionStatus';
describe('Presence micro service', () => {
it('should return connection as online when there is a connection online', () => {
expect(processConnectionStatus(UserStatus.OFFLINE, UserStatus.ONLINE)).to.equal(UserStatus.ONLINE);
expect(processConnectionStatus(UserStatus.ONLINE, UserStatus.ONLINE)).to.equal(UserStatus.ONLINE);
expect(processConnectionStatus(UserStatus.BUSY, UserStatus.ONLINE)).to.equal(UserStatus.ONLINE);
expect(processConnectionStatus(UserStatus.AWAY, UserStatus.ONLINE)).to.equal(UserStatus.ONLINE);
});
it('should return the connections status if the other connection is offline', () => {
expect(processConnectionStatus(UserStatus.OFFLINE, UserStatus.OFFLINE)).to.equal(UserStatus.OFFLINE);
expect(processConnectionStatus(UserStatus.ONLINE, UserStatus.OFFLINE)).to.equal(UserStatus.ONLINE);
expect(processConnectionStatus(UserStatus.AWAY, UserStatus.OFFLINE)).to.equal(UserStatus.AWAY);
});
it('should return the connection status when the default status is online', () => {
expect(processStatus(UserStatus.ONLINE, UserStatus.ONLINE)).to.equal(UserStatus.ONLINE);
expect(processStatus(UserStatus.AWAY, UserStatus.ONLINE)).to.equal(UserStatus.AWAY);
expect(processStatus(UserStatus.OFFLINE, UserStatus.ONLINE)).to.equal(UserStatus.OFFLINE);
});
it('should return status busy when the default status is busy', () => {
expect(processStatus(UserStatus.ONLINE, UserStatus.BUSY)).to.equal(UserStatus.BUSY);
expect(processStatus(UserStatus.AWAY, UserStatus.BUSY)).to.equal(UserStatus.BUSY);
expect(processStatus(UserStatus.OFFLINE, UserStatus.BUSY)).to.equal(UserStatus.OFFLINE);
});
it('should return status away when the default status is away', () => {
expect(processStatus(UserStatus.ONLINE, UserStatus.AWAY)).to.equal(UserStatus.AWAY);
expect(processStatus(UserStatus.AWAY, UserStatus.AWAY)).to.equal(UserStatus.AWAY);
expect(processStatus(UserStatus.OFFLINE, UserStatus.AWAY)).to.equal(UserStatus.OFFLINE);
});
it('should return status offline when the default status is offline', () => {
expect(processStatus(UserStatus.ONLINE, UserStatus.OFFLINE)).to.equal(UserStatus.OFFLINE);
expect(processStatus(UserStatus.AWAY, UserStatus.OFFLINE)).to.equal(UserStatus.OFFLINE);
expect(processStatus(UserStatus.OFFLINE, UserStatus.OFFLINE)).to.equal(UserStatus.OFFLINE);
});
it('should return correct status and statusConnection when connected once', () => {
expect(
processPresenceAndStatus(
[
{
id: 'random',
instanceId: 'random',
status: UserStatus.ONLINE,
_createdAt: new Date(),
_updatedAt: new Date(),
},
],
UserStatus.ONLINE,
),
).to.deep.equal({ status: UserStatus.ONLINE, statusConnection: UserStatus.ONLINE });
expect(
processPresenceAndStatus(
[
{
id: 'random',
instanceId: 'random',
status: UserStatus.AWAY,
_createdAt: new Date(),
_updatedAt: new Date(),
},
],
UserStatus.ONLINE,
),
).to.deep.equal({ status: UserStatus.AWAY, statusConnection: UserStatus.AWAY });
expect(
processPresenceAndStatus(
[
{
id: 'random',
instanceId: 'random',
status: UserStatus.ONLINE,
_createdAt: new Date(),
_updatedAt: new Date(),
},
],
UserStatus.BUSY,
),
).to.deep.equal({ status: UserStatus.BUSY, statusConnection: UserStatus.ONLINE });
expect(
processPresenceAndStatus(
[
{
id: 'random',
instanceId: 'random',
status: UserStatus.ONLINE,
_createdAt: new Date(),
_updatedAt: new Date(),
},
],
UserStatus.AWAY,
),
).to.deep.equal({ status: UserStatus.AWAY, statusConnection: UserStatus.ONLINE });
expect(
processPresenceAndStatus(
[
{
id: 'random',
instanceId: 'random',
status: UserStatus.AWAY,
_createdAt: new Date(),
_updatedAt: new Date(),
},
],
UserStatus.BUSY,
),
).to.deep.equal({ status: UserStatus.BUSY, statusConnection: UserStatus.AWAY });
expect(
processPresenceAndStatus(
[
{
id: 'random',
instanceId: 'random',
status: UserStatus.ONLINE,
_createdAt: new Date(),
_updatedAt: new Date(),
},
],
UserStatus.OFFLINE,
),
).to.deep.equal({ status: UserStatus.OFFLINE, statusConnection: UserStatus.ONLINE });
expect(
processPresenceAndStatus(
[
{
id: 'random',
instanceId: 'random',
status: UserStatus.AWAY,
_createdAt: new Date(),
_updatedAt: new Date(),
},
],
UserStatus.OFFLINE,
),
).to.deep.equal({ status: UserStatus.OFFLINE, statusConnection: UserStatus.AWAY });
});
it('should return correct status and statusConnection when connected twice', () => {
expect(
processPresenceAndStatus(
[
{
id: 'random',
instanceId: 'random',
status: UserStatus.ONLINE,
_createdAt: new Date(),
_updatedAt: new Date(),
},
{
id: 'random',
instanceId: 'random',
status: UserStatus.AWAY,
_createdAt: new Date(),
_updatedAt: new Date(),
},
],
UserStatus.ONLINE,
),
).to.deep.equal({ status: UserStatus.ONLINE, statusConnection: UserStatus.ONLINE });
expect(
processPresenceAndStatus(
[
{
id: 'random',
instanceId: 'random',
status: UserStatus.AWAY,
_createdAt: new Date(),
_updatedAt: new Date(),
},
{
id: 'random',
instanceId: 'random',
status: UserStatus.ONLINE,
_createdAt: new Date(),
_updatedAt: new Date(),
},
],
UserStatus.ONLINE,
),
).to.deep.equal({ status: UserStatus.ONLINE, statusConnection: UserStatus.ONLINE });
expect(
processPresenceAndStatus(
[
{
id: 'random',
instanceId: 'random',
status: UserStatus.AWAY,
_createdAt: new Date(),
_updatedAt: new Date(),
},
{
id: 'random',
instanceId: 'random',
status: UserStatus.AWAY,
_createdAt: new Date(),
_updatedAt: new Date(),
},
],
UserStatus.ONLINE,
),
).to.deep.equal({ status: UserStatus.AWAY, statusConnection: UserStatus.AWAY });
});
it('should return correct status and statusConnection when not connected', () => {
expect(processPresenceAndStatus([], UserStatus.ONLINE)).to.deep.equal({
status: UserStatus.OFFLINE,
statusConnection: UserStatus.OFFLINE,
});
expect(processPresenceAndStatus([], UserStatus.BUSY)).to.deep.equal({
status: UserStatus.OFFLINE,
statusConnection: UserStatus.OFFLINE,
});
expect(processPresenceAndStatus([], UserStatus.AWAY)).to.deep.equal({
status: UserStatus.OFFLINE,
statusConnection: UserStatus.OFFLINE,
});
expect(processPresenceAndStatus([], UserStatus.OFFLINE)).to.deep.equal({
status: UserStatus.OFFLINE,
statusConnection: UserStatus.OFFLINE,
});
});
});

View File

@ -1,8 +1,11 @@
import { IUserSessionConnection } from '../../../../../definition/IUserSession';
import { UserStatus } from '../../../../../definition/UserStatus';
/**
* Defines new connection status compared to a previous connection status
*/
export const processConnectionStatus = (current: UserStatus, status: UserStatus): UserStatus => {
if (status === UserStatus.ONLINE) {
if (current === UserStatus.ONLINE) {
return UserStatus.ONLINE;
}
if (status !== UserStatus.OFFLINE) {
@ -11,15 +14,32 @@ export const processConnectionStatus = (current: UserStatus, status: UserStatus)
return current;
};
export const processStatus = (statusConnection: UserStatus, statusDefault: UserStatus): UserStatus =>
statusConnection !== UserStatus.OFFLINE ? statusDefault : statusConnection;
/**
* Defines user's status based on presence and connection status
*/
export const processStatus = (statusConnection: UserStatus, statusDefault: UserStatus): UserStatus => {
if (statusConnection === UserStatus.OFFLINE) {
return statusConnection;
}
if (statusDefault === UserStatus.ONLINE) {
return statusConnection;
}
return statusDefault;
};
/**
* Defines user's status and connection status based on user's connections and default status
*/
export const processPresenceAndStatus = (
userSessions: IUserSessionConnection[] = [],
statusDefault = UserStatus.ONLINE,
): { status: UserStatus; statusConnection: UserStatus } => {
const statusConnection = userSessions.map((s) => s.status).reduce(processConnectionStatus, UserStatus.OFFLINE);
const status = processStatus(statusConnection, statusDefault);
return {
status,
statusConnection,