improve saveMessage (switch to class) and started to test
This commit is contained in:
parent
053213eecb
commit
1a63b3154a
@ -1,12 +1,13 @@
|
||||
const statusCode = require("../utils/statusCodes").statusCodes;
|
||||
const { getMessages } = require("../db/api.js");
|
||||
const { logger } = require("../system/Logger");
|
||||
|
||||
async function messages(body, res) {
|
||||
const { roomId } = body;
|
||||
getMessages(roomId).then((messages) => {
|
||||
res.status(statusCode.OK).json(messages);
|
||||
}).catch((err) => {
|
||||
console.log(err)
|
||||
logger.err(err)
|
||||
res.status(statusCode.INTERNAL_SERVER_ERROR);
|
||||
});
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
const statusCode = require("../utils/statusCodes").statusCodes;
|
||||
const { getRooms } = require("../db/api.js");
|
||||
const { logger } = require("../system/Logger");
|
||||
|
||||
async function rooms(body, res) {
|
||||
const { mailboxId, offset, limit } = body;
|
||||
getRooms(mailboxId).then((rooms) => {
|
||||
res.status(statusCode.OK).json(rooms);
|
||||
}).catch((err) => {
|
||||
console.log(err)
|
||||
logger.error(err)
|
||||
res.status(statusCode.INTERNAL_SERVER_ERROR);
|
||||
});
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ function execQueryAsyncWithId(query, values) {
|
||||
function execQuery(query, values) {
|
||||
db.query(query, values, (err, results, fields) => {
|
||||
if (err) {
|
||||
logger.err(err);
|
||||
logger.error(err);
|
||||
throw (err);
|
||||
}
|
||||
return results;
|
||||
|
@ -9,7 +9,7 @@ const {
|
||||
} = require("../db/saveMessageApp");
|
||||
|
||||
const { findRoomByOwner, getAddresseId, getUserIdOfMailbox } = require("../db/mail");
|
||||
const { isDmOnEnvelope, nbMembers } = require("./utils/statusUtils");
|
||||
const { nbMembers } = require("./utils/statusUtils");
|
||||
|
||||
/**
|
||||
* take object address and join mailbox and host to return mailbox@host
|
||||
@ -18,57 +18,99 @@ function createAddress(elt) {
|
||||
return `${elt.mailbox}@${elt.host}`;
|
||||
}
|
||||
|
||||
async function registerMessageInApp(messageId, attrs, boxId) {
|
||||
const isSeen = attrs.flags.includes("\\Seen") ? 1 : 0; // todo verify
|
||||
const envelope = attrs.envelope;
|
||||
async function initiateRoom(envelope, ownerId, messageId, isSeen) {
|
||||
await createRoom(envelope.subject, ownerId, messageId).then(async (roomId) => {
|
||||
// todo register members
|
||||
await registerMessageInRoom(messageId, roomId, isSeen, envelope.date);
|
||||
});
|
||||
}
|
||||
|
||||
await getAddresseId(createAddress(envelope.sender[0])).then(async (ownerId) => {
|
||||
if (envelope.inReplyTo) {
|
||||
await registerReplyMessage(envelope, messageId, isSeen, ownerId);
|
||||
} else {
|
||||
const userId = (await getUserIdOfMailbox(boxId))[0]?.user_id;
|
||||
if (ownerId == userId) {
|
||||
// send by the user
|
||||
if (nbMembers(envelope) == 2) {
|
||||
// this is a dm
|
||||
console.log(envelope)
|
||||
const userTo = (await getAddresseId(createAddress(envelope.to[0])));
|
||||
await findRoomByOwner(userTo).then(async (res) => {
|
||||
if (res.length == 0) {
|
||||
// first message of this conv with this sender
|
||||
await createRoom(envelope.subject, userTo, messageId).then(async (roomId) => {
|
||||
await registerMessageInRoom(messageId, roomId, isSeen, envelope.date);
|
||||
const roomType = {
|
||||
ROOM: 'room',
|
||||
CHANNEL: 'channel',
|
||||
GROUP: 'group',
|
||||
DM: 'dm',
|
||||
THREAD: 'thread'
|
||||
}
|
||||
|
||||
class registerMessageInApp {
|
||||
constructor(_messageId, _attrs, _boxId) {
|
||||
this.messageId = _messageId;
|
||||
this.attrs = _attrs;
|
||||
this.envelope = this.attrs.envelope;
|
||||
this.messageID = this.envelope.messageId;
|
||||
this.boxId = _boxId;
|
||||
this.isSeen = this.attrs.flags.includes("\\Seen") ? 1 : 0;
|
||||
this.ownerId;
|
||||
this.userId;
|
||||
}
|
||||
|
||||
async init() {
|
||||
this.ownerId = await getAddresseId(createAddress(this.envelope.sender[0])); // todo use sender or from ?
|
||||
}
|
||||
|
||||
isDm = () => nbMembers(this.envelope) == 2;
|
||||
|
||||
async isFromUs() {
|
||||
if (!this.userId) this.userId = (await getUserIdOfMailbox(boxId))[0]?.user_id;
|
||||
return this.ownerId = this.userId;
|
||||
}
|
||||
|
||||
async initiateRoom(owner, roomType) {
|
||||
// todo roomType
|
||||
await createRoom(this.envelope.subject, owner, this.messageId).then(async (roomId) => {
|
||||
// todo register members
|
||||
await registerMessageInRoom(this.messageId, roomId, this.isSeen, this.envelope.date);
|
||||
});
|
||||
}
|
||||
|
||||
async createOrRegisterOnExistence(owner, roomType) {
|
||||
await findRoomByOwner(owner).then(async (res) => {
|
||||
if (res.length == 0) {
|
||||
// first message with this sender
|
||||
await initiateRoom(owner, roomType);
|
||||
} else {
|
||||
// not a reply, add to the list of message if this sender
|
||||
await registerMessageInRoom(messageId, res[0].room_id, isSeen, envelope.date);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// message coming from user with multiple member is a group
|
||||
await createRoom(envelope.subject, ownerId, messageId).then(async (roomId) => {
|
||||
await registerMessageInRoom(messageId, roomId, isSeen, envelope.date);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
await findRoomByOwner(ownerId).then(async (res) => {
|
||||
if (res.length == 0) {
|
||||
// first message of this sender
|
||||
if (!envelope.subject) console.error(envelope)
|
||||
await createRoom(envelope.subject, ownerId, messageId).then(async (roomId) => {
|
||||
await registerMessageInRoom(messageId, roomId, isSeen, envelope.date);
|
||||
});
|
||||
} else {
|
||||
// not a reply, add to the list of message if this sender
|
||||
await registerMessageInRoom(messageId, res[0].room_id, isSeen, envelope.date);
|
||||
}
|
||||
});
|
||||
}
|
||||
await registerMessageInRoom(this.messageId, res[0].room_id, this.isSeen, this.envelope.date);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function registerReplyMessage(envelope, messageId, isSeen, ownerId) {
|
||||
async createOrRegisterOnMembers(roomId) {
|
||||
const hasSameMembers = await hasSameMembersAsParent(this.messageID, this.envelope.inReplyTo);
|
||||
if (hasSameMembers) {
|
||||
await registerMessageInRoom(this.messageId, roomId, this.isSeen, this.envelope.date);
|
||||
} else {
|
||||
await createThread(this.envelope.subject, this.ownerId, this.messageId, roomId, this.isDm()).then(
|
||||
async (threadId) => {
|
||||
await registerMessageInThread(this.messageId, threadId, this.isSeen);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async save() {
|
||||
await this.init();
|
||||
if (this.envelope.inReplyTo) {
|
||||
this.saveReply();
|
||||
} else {
|
||||
if (await this.isFromUs()) {
|
||||
if (this.isDm()) {
|
||||
// create or add new message to DM
|
||||
const userTo = await getAddresseId(createAddress(this.envelope.to[0]));
|
||||
await this.createOrRegisterOnExistence(userTo, roomType.DM);
|
||||
} else {
|
||||
// it is not a reply and not a dm
|
||||
// so it is a channel, which can be possibly a group
|
||||
initiateRoom(this.envelope, this.ownerId, this.messageId, this.isSeen);
|
||||
}
|
||||
} else {
|
||||
await this.createOrRegisterOnExistence(this.ownerId, roomType.ROOM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async saveReply() {
|
||||
const messageID = envelope.messageId;
|
||||
await findRoomsFromMessage(messageId).then(async (rooms) => {
|
||||
if (rooms.length == 0) {
|
||||
@ -76,20 +118,10 @@ async function registerReplyMessage(envelope, messageId, isSeen, ownerId) {
|
||||
// todo test if members of transferred message are included
|
||||
} else if (rooms.length === 1) {
|
||||
// only one room so message is only in a room and not in a thread
|
||||
// as a thread is associated to a room to begin
|
||||
// as a thread is associated to a room
|
||||
await isRoomGroup(rooms[0].room_id).then(async (isGroup) => {
|
||||
if (isGroup) {
|
||||
const hasSameMembers = await hasSameMembersAsParent(messageID, envelope.inReplyTo);
|
||||
if (hasSameMembers) {
|
||||
await registerMessageInRoom(messageId, rooms[0].room_id, isSeen, envelope.date);
|
||||
} else {
|
||||
// is a group and has not the same member as the previous message
|
||||
// some recipient has been removed create a thread
|
||||
const isDm = isDmOnEnvelope(envelope);
|
||||
await createThread(envelope.subject, ownerId, messageId, rooms[0].room_id, isDm).then(async (threadId) => {
|
||||
await registerMessageInThread(messageId, threadId, isSeen);
|
||||
});
|
||||
}
|
||||
this.createOrRegisterOnMembers(rooms[0].room_id);
|
||||
} else {
|
||||
// reply from channel
|
||||
// todo
|
||||
@ -100,23 +132,14 @@ async function registerReplyMessage(envelope, messageId, isSeen, ownerId) {
|
||||
});
|
||||
} else if (rooms.length > 1) {
|
||||
// get the lowest thread (order by room_id)
|
||||
const room = rooms[rooms.length-1];
|
||||
const hasSameMembers = await hasSameMembersAsParent(messageID, envelope.inReplyTo);
|
||||
if (hasSameMembers) {
|
||||
await registerMessageInThread(messageId, room.room_id, isSeen);
|
||||
} else {
|
||||
// has not the same members so it is a derivation of this thread
|
||||
// todo put this in a function and add default message in the reply chain
|
||||
const isDm = isDmOnEnvelope(envelope);
|
||||
await createThread(envelope.subject, ownerId, messageId, room.room_id, isDm).then(async (threadId) => {
|
||||
await registerMessageInThread(messageId, threadId, isSeen);
|
||||
});
|
||||
}
|
||||
const roomId = rooms[rooms.length - 1].room_id;
|
||||
this.createOrRegisterOnMembers(roomId);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
registerMessageInApp
|
||||
registerMessageInApp,
|
||||
roomType
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
function isDmOnEnvelope(envelope) {
|
||||
return nbMembers(envelope) === 2;
|
||||
}
|
||||
|
||||
function nbMembers(envelope) {
|
||||
let nbMembers =
|
||||
(envelope.bcc?.length ?? 0) +
|
||||
@ -18,6 +14,5 @@ function nbMembers(envelope) {
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isDmOnEnvelope,
|
||||
nbMembers,
|
||||
};
|
||||
|
@ -1,52 +1,40 @@
|
||||
process.env["NODE_DEV"] = "TEST";
|
||||
const { saveFromParsedData } = require("../../mails/storeMessage");
|
||||
const { TestDb } = require("../sql/test-utilsDb");
|
||||
const MYSQL = require("../../db/config.json").MYSQL;
|
||||
const { getAddresseId } = require("../../db/mail");
|
||||
const { generateAttrs, generateUsers } = require("../test-utils/test-attrsUtils");
|
||||
const { registerMessageInApp, roomType } = require("../../mails/saveMessage");
|
||||
|
||||
let db;
|
||||
beforeAll(async () => {
|
||||
const options = {
|
||||
databaseOptions: {
|
||||
host: "localhost",
|
||||
port: 3306,
|
||||
user: MYSQL.user,
|
||||
password: MYSQL.pwd,
|
||||
database: "mail_test",
|
||||
},
|
||||
dbSchema: "../../sql/structureV2.sql",
|
||||
};
|
||||
db = new TestDb(options);
|
||||
await db.init();
|
||||
});
|
||||
jest.mock("../../db/mail");
|
||||
|
||||
afterAll(async () => {
|
||||
db.cleanTables();
|
||||
});
|
||||
// todo mock db
|
||||
|
||||
describe("saveMessage", async () => {
|
||||
describe("rooms", async () => {
|
||||
it("messages not related and from same sender should be in the same room", async () => {
|
||||
await saveFromParsedData(
|
||||
{
|
||||
to: { value: [{ address: "address1@email.com" }] },
|
||||
from: { value: [{ address: "address2@email.com" }] },
|
||||
messageId: "<messageId1>",
|
||||
},
|
||||
1,
|
||||
);
|
||||
await saveFromParsedData(
|
||||
{
|
||||
to: { value: [{ address: "address1@email.com" }] },
|
||||
from: { value: [{ address: "address2@email.com" }] },
|
||||
messageId: "<messageId2>",
|
||||
},
|
||||
2,
|
||||
);
|
||||
// todo call parser
|
||||
const query = ""
|
||||
db.execQueryAsync().then((res) => {
|
||||
expect(res.length).toBe(2);
|
||||
})
|
||||
describe("saveMessage", () => {
|
||||
describe("is not a reply", () => {
|
||||
it("first DM from user should create a DM room", async () => {
|
||||
const users = generateUsers(2);
|
||||
const attrs = generateAttrs({ from: [users[0].user], to: [users[1].user] });
|
||||
|
||||
getAddresseId.mockReturnValue(users[1].id);
|
||||
|
||||
const register = new registerMessageInApp(1, attrs, 1);
|
||||
register.ownerId = users[0].id;
|
||||
|
||||
jest.spyOn(register, "isFromUs").mockReturnValue(true);
|
||||
jest.spyOn(register, "init").mockReturnValue("");
|
||||
|
||||
const createOrRegisterOnExistence = jest
|
||||
.spyOn(register, "createOrRegisterOnExistence")
|
||||
.mockImplementation(() => undefined);
|
||||
|
||||
await register.save();
|
||||
|
||||
expect(createOrRegisterOnExistence).toHaveBeenCalledWith(users[1].id, roomType.DM);
|
||||
});
|
||||
// it("DM message from user should be added to DM room", async () => {
|
||||
|
||||
// });
|
||||
// it("first GROUP message should create a group", () => {});
|
||||
});
|
||||
describe("replies", () => {
|
||||
it("", () => {});
|
||||
});
|
||||
describe("", () => {});
|
||||
});
|
||||
|
206
back/test/test-utils/names.js
Normal file
206
back/test/test-utils/names.js
Normal file
@ -0,0 +1,206 @@
|
||||
const names = [
|
||||
"James",
|
||||
"Mary",
|
||||
"Robert",
|
||||
"Patricia",
|
||||
"John",
|
||||
"Jennifer",
|
||||
"Michael",
|
||||
"Linda",
|
||||
"David",
|
||||
"Elizabeth",
|
||||
"William",
|
||||
"Barbara",
|
||||
"Richard",
|
||||
"Susan",
|
||||
"Joseph",
|
||||
"Jessica",
|
||||
"Thomas",
|
||||
"Sarah",
|
||||
"Charles",
|
||||
"Karen",
|
||||
"Christopher",
|
||||
"Lisa",
|
||||
"Daniel",
|
||||
"Nancy",
|
||||
"Matthew",
|
||||
"Betty",
|
||||
"Anthony",
|
||||
"Margaret",
|
||||
"Mark",
|
||||
"Sandra",
|
||||
"Donald",
|
||||
"Ashley",
|
||||
"Steven",
|
||||
"Kimberly",
|
||||
"Paul",
|
||||
"Emily",
|
||||
"Andrew",
|
||||
"Donna",
|
||||
"Joshua",
|
||||
"Michelle",
|
||||
"Kenneth",
|
||||
"Carol",
|
||||
"Kevin",
|
||||
"Amanda",
|
||||
"Brian",
|
||||
"Dorothy",
|
||||
"George",
|
||||
"Melissa",
|
||||
"Timothy",
|
||||
"Deborah",
|
||||
"Ronald",
|
||||
"Stephanie",
|
||||
"Edward",
|
||||
"Rebecca",
|
||||
"Jason",
|
||||
"Sharon",
|
||||
"Jeffrey",
|
||||
"Laura",
|
||||
"Ryan",
|
||||
"Cynthia",
|
||||
"Jacob",
|
||||
"Kathleen",
|
||||
"Gary",
|
||||
"Amy",
|
||||
"Nicholas",
|
||||
"Angela",
|
||||
"Eric",
|
||||
"Shirley",
|
||||
"Jonathan",
|
||||
"Anna",
|
||||
"Stephen",
|
||||
"Brenda",
|
||||
"Larry",
|
||||
"Pamela",
|
||||
"Justin",
|
||||
"Emma",
|
||||
"Scott",
|
||||
"Nicole",
|
||||
"Brandon",
|
||||
"Helen",
|
||||
"Benjamin",
|
||||
"Samantha",
|
||||
"Samuel",
|
||||
"Katherine",
|
||||
"Gregory",
|
||||
"Christine",
|
||||
"Alexander",
|
||||
"Debra",
|
||||
"Frank",
|
||||
"Rachel",
|
||||
"Patrick",
|
||||
"Carolyn",
|
||||
"Raymond",
|
||||
"Janet",
|
||||
"Jack",
|
||||
"Catherine",
|
||||
"Dennis",
|
||||
"Maria",
|
||||
"Jerry",
|
||||
"Heather",
|
||||
"Tyler",
|
||||
"Diane",
|
||||
"Aaron",
|
||||
"Ruth",
|
||||
"Jose",
|
||||
"Julie",
|
||||
"Adam",
|
||||
"Olivia",
|
||||
"Nathan",
|
||||
"Joyce",
|
||||
"Henry",
|
||||
"Virginia",
|
||||
"Douglas",
|
||||
"Victoria",
|
||||
"Zachary",
|
||||
"Kelly",
|
||||
"Peter",
|
||||
"Lauren",
|
||||
"Kyle",
|
||||
"Christina",
|
||||
"Ethan",
|
||||
"Joan",
|
||||
"Walter",
|
||||
"Evelyn",
|
||||
"Noah",
|
||||
"Judith",
|
||||
"Jeremy",
|
||||
"Megan",
|
||||
"Christian",
|
||||
"Andrea",
|
||||
"Keith",
|
||||
"Cheryl",
|
||||
"Roger",
|
||||
"Hannah",
|
||||
"Terry",
|
||||
"Jacqueline",
|
||||
"Gerald",
|
||||
"Martha",
|
||||
"Harold",
|
||||
"Gloria",
|
||||
"Sean",
|
||||
"Teresa",
|
||||
"Austin",
|
||||
"Ann",
|
||||
"Carl",
|
||||
"Sara",
|
||||
"Arthur",
|
||||
"Madison",
|
||||
"Lawrence",
|
||||
"Frances",
|
||||
"Dylan",
|
||||
"Kathryn",
|
||||
"Jesse",
|
||||
"Janice",
|
||||
"Jordan",
|
||||
"Jean",
|
||||
"Bryan",
|
||||
"Abigail",
|
||||
"Billy",
|
||||
"Alice",
|
||||
"Joe",
|
||||
"Julia",
|
||||
"Bruce",
|
||||
"Judy",
|
||||
"Gabriel",
|
||||
"Sophia",
|
||||
"Logan",
|
||||
"Grace",
|
||||
"Albert",
|
||||
"Denise",
|
||||
"Willie",
|
||||
"Amber",
|
||||
"Alan",
|
||||
"Doris",
|
||||
"Juan",
|
||||
"Marilyn",
|
||||
"Wayne",
|
||||
"Danielle",
|
||||
"Elijah",
|
||||
"Beverly",
|
||||
"Randy",
|
||||
"Isabella",
|
||||
"Roy",
|
||||
"Theresa",
|
||||
"Vincent",
|
||||
"Diana",
|
||||
"Ralph",
|
||||
"Natalie",
|
||||
"Eugene",
|
||||
"Brittany",
|
||||
"Russell",
|
||||
"Charlotte",
|
||||
"Bobby",
|
||||
"Marie",
|
||||
"Mason",
|
||||
"Kayla",
|
||||
"Philip",
|
||||
"Alexis",
|
||||
"Louis",
|
||||
"Lori"
|
||||
];
|
||||
|
||||
module.exports = {
|
||||
names
|
||||
}
|
@ -12,5 +12,8 @@ export default {
|
||||
},
|
||||
getMessages(roomId) {
|
||||
return API().get(`/mail/${roomId}/messages`);
|
||||
}
|
||||
},
|
||||
getMembers(roomId) {
|
||||
return API().get(`/mail/${roomId}/members`);
|
||||
},
|
||||
}
|
@ -39,7 +39,7 @@ onMounted(() => {
|
||||
<template>
|
||||
<div class="message">
|
||||
<div id="context">
|
||||
<div class="left" id="profile">Carrefour@emailing .carrefor.fr "carrefour"</div>
|
||||
<div class="left" id="profile">{{ props.data.fromA }}</div>
|
||||
<div class="middle">{{ decodeEmojis(props.data.subject) }}</div>
|
||||
<div class="right" id="date">
|
||||
{{
|
||||
|
Loading…
Reference in New Issue
Block a user