implement database as a class for tests
This commit is contained in:
parent
9c16e06446
commit
5a71e104cd
@ -35,21 +35,13 @@ export async function createRoom(
|
||||
}
|
||||
|
||||
// todo date not good
|
||||
export async function registerMessageInRoom(
|
||||
messageId: number,
|
||||
roomId: number,
|
||||
isSeen: boolean,
|
||||
idate: string | undefined | null,
|
||||
) {
|
||||
export async function registerMessageInRoom(messageId: number, roomId: number, idate: string | undefined | null) {
|
||||
if (!idate) idate = new Date().toString();
|
||||
const query = `INSERT IGNORE INTO app_room_message (message_id, room_id) VALUES (?, ?)`;
|
||||
const values = [messageId, roomId];
|
||||
await execQueryAsync(query, values);
|
||||
|
||||
updateLastUpdateRoom(roomId, idate);
|
||||
// if (!isSeen) {
|
||||
// incrementNotSeenRoom(roomId);
|
||||
// }
|
||||
}
|
||||
|
||||
export function updateLastUpdateRoom(roomId: number, idate: string) {
|
||||
@ -58,11 +50,13 @@ export function updateLastUpdateRoom(roomId: number, idate: string) {
|
||||
execQuery(query, values);
|
||||
}
|
||||
|
||||
export function incrementNotSeenRoom(roomId: number) {
|
||||
// todo
|
||||
export async function incrementNotSeenRoom(roomId: number) {
|
||||
const query = `UPDATE app_room SET unseen = unseen + 1 WHERE room_id = ?`;
|
||||
const values = [roomId];
|
||||
execQuery(query, values);
|
||||
}
|
||||
|
||||
export async function getRoomInfo(messageID: string): Promise<{ room_id: number; root_id: number }[]> {
|
||||
export async function getThreadInfo(messageID: string): Promise<{ room_id: number; root_id: number }[]> {
|
||||
const query = `
|
||||
SELECT
|
||||
app_room.room_id
|
||||
@ -92,9 +86,13 @@ export async function isRoomGroup(roomId: number): Promise<boolean> {
|
||||
});
|
||||
}
|
||||
|
||||
export async function findRoomsFromMessage(messageID: string) {
|
||||
export async function findRoomsFromMessage(messageID: string): Promise<{ room_id: number }[]> {
|
||||
// todo find message in room not started
|
||||
const query = `SELECT room_id FROM app_room_message WHERE message_id = ? ORDER BY room_id`;
|
||||
const query = `
|
||||
SELECT room_id FROM app_room_message
|
||||
INNER JOIN message ON message.message_id = app_room_message.message_id
|
||||
WHERE message.messageID = ? ORDER BY room_id
|
||||
`;
|
||||
const values = [messageID];
|
||||
return await execQueryAsync(query, values);
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ export async function findRoomByOwner(ownerId: number): Promise<{ room_id: numbe
|
||||
}
|
||||
|
||||
export async function getUserIdOfMailbox(boxId: number): Promise<{ user_id: number }[]> {
|
||||
console.log("fuckdsvreghiu")
|
||||
const query = `
|
||||
SELECT app_account.user_id
|
||||
FROM mailbox
|
||||
|
||||
@ -7,7 +7,8 @@ import {
|
||||
registerThread,
|
||||
registerMember,
|
||||
getAllMembers,
|
||||
getRoomInfo,
|
||||
getThreadInfo,
|
||||
incrementNotSeenRoom,
|
||||
} from "../db/saveMessage-db";
|
||||
|
||||
import { findRoomByOwner, getAddresseId, getUserIdOfMailbox } from "../db/utils/mail";
|
||||
@ -22,13 +23,13 @@ function createAddress(elt: User): string {
|
||||
return `${elt.mailbox}@${elt.host}`;
|
||||
}
|
||||
|
||||
export const roomType = {
|
||||
ROOM: 0,
|
||||
CHANNEL: 1,
|
||||
GROUP: 2,
|
||||
DM: 3,
|
||||
THREAD: 4,
|
||||
};
|
||||
export enum RoomType {
|
||||
ROOM = 0,
|
||||
CHANNEL = 1,
|
||||
GROUP = 2,
|
||||
DM = 3,
|
||||
THREAD = 4,
|
||||
}
|
||||
|
||||
export default class RegisterMessageInApp {
|
||||
messageId: number;
|
||||
@ -73,6 +74,12 @@ export default class RegisterMessageInApp {
|
||||
return this.ownerId == this.userId;
|
||||
}
|
||||
|
||||
async incrementNotSeen(roomId: number) {
|
||||
if (!this.isSeen) {
|
||||
await incrementNotSeenRoom(roomId);
|
||||
}
|
||||
}
|
||||
|
||||
async registerMembers(roomId: number) {
|
||||
getAllMembers(this.messageId).then((res) => {
|
||||
const data = res[0].id.split(",");
|
||||
@ -82,42 +89,49 @@ export default class RegisterMessageInApp {
|
||||
});
|
||||
}
|
||||
|
||||
async initiateRoom(owner: number, roomType: number) {
|
||||
async initiateRoom(owner: number, roomType: RoomType) {
|
||||
try {
|
||||
const roomId = await createRoom(this.envelope.subject, owner, this.messageId, roomType);
|
||||
await registerMessageInRoom(this.messageId, roomId, this.isSeen, this.envelope.date);
|
||||
this.registerMembers(roomId);
|
||||
await registerMessageInRoom(this.messageId, roomId, this.envelope.date);
|
||||
await this.incrementNotSeen(roomId);
|
||||
await this.registerMembers(roomId);
|
||||
return roomId;
|
||||
} catch (err) {
|
||||
logger.err(err);
|
||||
}
|
||||
}
|
||||
|
||||
async createOrRegisterOnExistence(owner: number, roomType: number) {
|
||||
async createOrRegisterOnExistence(owner: number, roomType: RoomType) {
|
||||
await findRoomByOwner(owner).then(async (res) => {
|
||||
if (res.length == 0) {
|
||||
// first message with this sender
|
||||
await this.initiateRoom(owner, roomType);
|
||||
} else {
|
||||
// not a reply, add to the list of message if this sender
|
||||
await registerMessageInRoom(this.messageId, res[0].room_id, this.isSeen, this.envelope.date);
|
||||
await registerMessageInRoom(this.messageId, res[0].room_id, this.envelope.date);
|
||||
await this.incrementNotSeen(res[0].room_id);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async initiateThread() {
|
||||
await createRoom(this.envelope.subject, this.ownerId, this.messageId, roomType.THREAD).then(
|
||||
async (roomId: number) => {
|
||||
await createRoom(this.envelope.subject, this.ownerId, this.messageId, RoomType.THREAD).then(
|
||||
async (threadId: number) => {
|
||||
// find parent room infos
|
||||
await getRoomInfo(this.inReplyTo).then(async (room) => {
|
||||
let roomId: number;
|
||||
await getThreadInfo(this.inReplyTo).then(async (room) => {
|
||||
// todo room not lenght, reply to transfer ?
|
||||
roomId = room[0].room_id;
|
||||
let root_id = room[0].root_id;
|
||||
if (!root_id) root_id = room[0].room_id;
|
||||
await registerThread(roomId, room[0].room_id, root_id);
|
||||
if (!root_id) root_id = roomId;
|
||||
await registerThread(threadId, room[0].room_id, root_id);
|
||||
});
|
||||
// impl register previous message ?
|
||||
await registerMessageInRoom(this.messageId, roomId, this.isSeen, this.envelope.date);
|
||||
await this.registerMembers(roomId);
|
||||
// impl register previous message or go back
|
||||
await registerMessageInRoom(this.messageId, threadId, this.envelope.date);
|
||||
await this.incrementNotSeen(roomId);
|
||||
await this.incrementNotSeen(threadId);
|
||||
await this.registerMembers(threadId);
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -125,7 +139,8 @@ export default class RegisterMessageInApp {
|
||||
async createOrRegisterOnMembers(roomId: number) {
|
||||
const hasSameMembers = await hasSameMembersAsParent(this.messageId, this.inReplyTo);
|
||||
if (hasSameMembers) {
|
||||
await registerMessageInRoom(this.messageId, roomId, this.isSeen, this.envelope.date);
|
||||
await registerMessageInRoom(this.messageId, roomId, this.envelope.date);
|
||||
await this.incrementNotSeen(roomId);
|
||||
} else {
|
||||
await this.initiateThread();
|
||||
}
|
||||
@ -142,21 +157,21 @@ export default class RegisterMessageInApp {
|
||||
// create or add new message to DM
|
||||
if (!this.envelope.to) throw new Error("Who send a DM and put the recipient in cc ?");
|
||||
const userTo = await getAddresseId(createAddress(this.envelope.to[0]));
|
||||
await this.createOrRegisterOnExistence(userTo, roomType.DM);
|
||||
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
|
||||
this.initiateRoom(this.ownerId, roomType.ROOM);
|
||||
this.initiateRoom(this.ownerId, RoomType.ROOM);
|
||||
}
|
||||
} else {
|
||||
await this.createOrRegisterOnExistence(this.ownerId, roomType.ROOM);
|
||||
await this.createOrRegisterOnExistence(this.ownerId, RoomType.ROOM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async saveReply() {
|
||||
await findRoomsFromMessage(this.inReplyTo).then(async (rooms) => {
|
||||
if (rooms.length == 0) {
|
||||
if (rooms.length < 1) {
|
||||
// no rooms, so is a transfer
|
||||
// todo test if members of transferred message are included
|
||||
} else if (rooms.length === 1) {
|
||||
|
||||
@ -1,18 +1,31 @@
|
||||
import mysql from "mysql";
|
||||
|
||||
jest.mock("mysql");
|
||||
import mysql from "mysql";
|
||||
mysql.createConnection = jest.fn();
|
||||
mysql.createConnection.mockImplementation(() => {
|
||||
return { connect: () => new Promise((resolve, rejects) => resolve(true)) };
|
||||
});
|
||||
|
||||
import { generateAttrs, generateUsers } from "../test-utils/test-attrsUtils";
|
||||
import registerMessageInApp, { roomType } from "../../mails/saveMessage";
|
||||
import { jest, describe, it, expect } from "@jest/globals";
|
||||
import saveMessageDatabase from "../test-utils/db/test-saveMessage";
|
||||
|
||||
import { generateAttrs, generateUsers } from "../test-utils/test-attrsUtils";
|
||||
import registerMessageInApp, { RoomType } from "../../mails/saveMessage";
|
||||
import { jest, describe, it, expect } from "@jest/globals";
|
||||
import { mocked } from "jest-mock";
|
||||
|
||||
const db = new saveMessageDatabase(generateUsers(5));
|
||||
|
||||
const ownUser = db.users[0];
|
||||
const messageId = 1;
|
||||
const boxId = 1;
|
||||
jest.mock("../../db/utils/mail", () => {
|
||||
return {
|
||||
getAddresseId: jest.fn(),
|
||||
getUserIdOfMailbox: jest.fn(),
|
||||
};
|
||||
});
|
||||
import { getAddresseId, getUserIdOfMailbox } from "../../db/utils/mail";
|
||||
|
||||
// todo esbuild
|
||||
// todo mock db
|
||||
// new message from us
|
||||
// to multiple people -> room
|
||||
// if response has same member => group
|
||||
@ -27,36 +40,24 @@ import { getAddresseId, getUserIdOfMailbox } from "../../db/utils/mail";
|
||||
// // make it better
|
||||
// if multiple members reply -> group
|
||||
// if only me reply -> channel
|
||||
const users = generateUsers(5);
|
||||
const ownUser = users[0];
|
||||
const messageId = 1;
|
||||
const boxId = 1;
|
||||
|
||||
jest.mock("../../db/utils/mail", () => ({
|
||||
getAddresseId: jest.fn().mockImplementation((email) => {
|
||||
const match = users.find((user) => user.user.mailbox + "@" + user.user.host == email);
|
||||
return new Promise((resolve, reject) => resolve(match?.id));
|
||||
}),
|
||||
getUserIdOfMailbox: jest.fn().mockImplementation((boxId) => {
|
||||
return new Promise((resolve, reject) => resolve([{ user_id: ownUser.id }]));
|
||||
}),
|
||||
}));
|
||||
|
||||
beforeAll(async () => {
|
||||
|
||||
db.clear();
|
||||
mocked(getAddresseId).mockImplementation(db.getAddresseId);
|
||||
mocked(getUserIdOfMailbox).mockImplementation(db.getUserIdOfMailbox);
|
||||
});
|
||||
|
||||
describe("saveMessage", () => {
|
||||
describe("functions", () => {
|
||||
it("isFromUs", async () => {
|
||||
const attrs = generateAttrs({ from: [ownUser.user], to: [users[1].user] });
|
||||
const attrs = generateAttrs({ from: [ownUser.user], to: [db.users[1].user] });
|
||||
const register = new registerMessageInApp(messageId, attrs, boxId);
|
||||
await register.init();
|
||||
const res = await register.isFromUs();
|
||||
|
||||
expect(res).toBe(true);
|
||||
|
||||
const attrs2 = generateAttrs({ from: [users[2].user], to: [users[1].user] });
|
||||
const attrs2 = generateAttrs({ from: [db.users[2].user], to: [db.users[1].user] });
|
||||
const register2 = new registerMessageInApp(messageId, attrs2, boxId);
|
||||
await register2.init();
|
||||
const res2 = await register2.isFromUs();
|
||||
@ -67,56 +68,56 @@ describe("saveMessage", () => {
|
||||
describe("implementation", () => {
|
||||
describe("new first message from us", () => {
|
||||
it("new first message from us to one recipient should create a DM", async () => {
|
||||
const attrs = generateAttrs({ from: [ownUser.user], to: [users[1].user] });
|
||||
const attrs = generateAttrs({ from: [ownUser.user], to: [db.users[1].user] });
|
||||
|
||||
const register = new registerMessageInApp(messageId, attrs, boxId);
|
||||
|
||||
const createOrRegisterOnExistence = jest
|
||||
.spyOn(register, "createOrRegisterOnExistence")
|
||||
.mockImplementation(
|
||||
(owner: number, roomType: number) => new Promise((resolve, reject) => resolve()),
|
||||
(owner: number, roomType: RoomType) => new Promise((resolve, reject) => resolve()),
|
||||
);
|
||||
|
||||
await register.save();
|
||||
|
||||
expect(createOrRegisterOnExistence).toHaveBeenCalledWith(users[1].id, roomType.DM);
|
||||
expect(createOrRegisterOnExistence).toHaveBeenCalledWith(db.users[1].id, RoomType.DM);
|
||||
});
|
||||
it("new first message from us to multiple recipients should create a ROOM", async () => {
|
||||
const attrs = generateAttrs({ from: [ownUser.user], to: [users[1].user, users[2].user] });
|
||||
const attrs = generateAttrs({ from: [ownUser.user], to: [db.users[1].user, db.users[2].user] });
|
||||
|
||||
const register = new registerMessageInApp(messageId, attrs, boxId);
|
||||
|
||||
const initiateRoom = jest
|
||||
.spyOn(register, "initiateRoom")
|
||||
.mockImplementation((owner: number, roomType: number) => Promise.resolve(1));
|
||||
.mockImplementation((owner: number, roomType: RoomType) => Promise.resolve(1));
|
||||
|
||||
await register.save();
|
||||
|
||||
expect(initiateRoom).toHaveBeenCalledWith(ownUser.id, roomType.ROOM);
|
||||
expect(initiateRoom).toHaveBeenCalledWith(ownUser.id, RoomType.ROOM);
|
||||
});
|
||||
// it("response to new first message to multiple recipients with same members should change room type to GROUP", () => {});
|
||||
// it("response to new first message to multiple recipients with different members should change room type to CHANNEL", () => {});
|
||||
});
|
||||
describe("new first message from other", () => {
|
||||
it("new first message from other to me only should create a room", async () => {
|
||||
const attrs = generateAttrs({ from: [users[1].user], to: [ownUser.user] });
|
||||
const attrs = generateAttrs({ from: [db.users[1].user], to: [ownUser.user] });
|
||||
|
||||
const register = new registerMessageInApp(messageId, attrs, boxId);
|
||||
|
||||
const createOrRegisterOnExistence = jest
|
||||
.spyOn(register, "createOrRegisterOnExistence")
|
||||
.mockImplementation((owner: number, roomType: number) => {
|
||||
.mockImplementation((owner: number, roomType: RoomType) => {
|
||||
return new Promise((resolve, reject) => resolve());
|
||||
});
|
||||
|
||||
await register.save();
|
||||
|
||||
expect(createOrRegisterOnExistence).toHaveBeenCalledWith(users[1].id, roomType.ROOM);
|
||||
expect(createOrRegisterOnExistence).toHaveBeenCalledWith(db.users[1].id, RoomType.ROOM);
|
||||
});
|
||||
});
|
||||
// describe("replies", () => {
|
||||
// it("", () => {});
|
||||
// });
|
||||
// describe("", () => {});
|
||||
describe("unseen behavior", () => {});
|
||||
});
|
||||
});
|
||||
|
||||
@ -0,0 +1,123 @@
|
||||
import { RoomType } from "../../../mails/saveMessage";
|
||||
import { generateUsers } from "../test-attrsUtils";
|
||||
|
||||
interface Room {
|
||||
room_id: number;
|
||||
room_name: string;
|
||||
owner_id: number;
|
||||
message_id: number;
|
||||
room_type: RoomType;
|
||||
notSeen: number;
|
||||
lastUpdate: string;
|
||||
is_thread?: boolean;
|
||||
parent_id?: number;
|
||||
root_id?: number;
|
||||
}
|
||||
|
||||
export default class saveMessageDatabase {
|
||||
rooms: Room[];
|
||||
roomId: number;
|
||||
messages: { room_id: number; message_id: number }[];
|
||||
users: any[];
|
||||
|
||||
constructor(_users) {
|
||||
this.rooms = [];
|
||||
this.messages = [];
|
||||
this.users = generateUsers(5);
|
||||
this.roomId = 0;
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.rooms = [];
|
||||
this.messages = [];
|
||||
this.roomId = 0;
|
||||
}
|
||||
|
||||
_findRoomById(roomId: number): Room {
|
||||
return this.rooms.find((room) => room.room_id === roomId);
|
||||
}
|
||||
|
||||
createRoom(roomName: string | null | undefined, ownerId: number, messageId: number, roomType: RoomType) {
|
||||
this.rooms.push({
|
||||
room_id: this.roomId,
|
||||
room_name: roomName,
|
||||
owner_id: ownerId,
|
||||
message_id: messageId,
|
||||
room_type: roomType,
|
||||
notSeen: 0,
|
||||
lastUpdate: "0",
|
||||
});
|
||||
this.roomId++;
|
||||
}
|
||||
|
||||
registerMessageInRoom = (messageId: number, roomId: number, idate: string | undefined | null) => {
|
||||
this.messages.push({ message_id: messageId, room_id: roomId });
|
||||
};
|
||||
|
||||
isRoomGroup(roomId: number): Promise<boolean> {
|
||||
return new Promise((resolve, reject) => {
|
||||
resolve(this.rooms.find((room) => room.room_id == roomId).room_type === RoomType.GROUP);
|
||||
});
|
||||
}
|
||||
|
||||
findRoomsFromMessage = (messageID: string): Promise<{ room_id: number }[]> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const rooms = this.rooms.filter((room) => room.message_id.toString() === messageID);
|
||||
const res: { room_id: number }[] = [];
|
||||
rooms.forEach((room) => {
|
||||
res.push({ room_id: room.room_id });
|
||||
});
|
||||
resolve(res);
|
||||
});
|
||||
};
|
||||
|
||||
hasSameMembersAsParent() {
|
||||
// test_todo
|
||||
}
|
||||
|
||||
registerThread = async (roomId: number, parentId: number, rootId: number) => {
|
||||
const room = this._findRoomById(roomId);
|
||||
room.parent_id = parentId;
|
||||
room.room_id = rootId;
|
||||
};
|
||||
|
||||
registerMember() {
|
||||
// test_todo
|
||||
}
|
||||
|
||||
getAllMembers() {
|
||||
// test_todo
|
||||
}
|
||||
|
||||
getThreadInfo = (messageID: string): Promise<{ room_id: number; root_id: number }[]> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const room = this.rooms.find((room) => room.message_id.toString() === messageID);
|
||||
resolve([{ room_id: room.room_id, root_id: room.root_id }]);
|
||||
});
|
||||
};
|
||||
|
||||
incrementNotSeenRoom = (roomId: number) => {
|
||||
const room = this._findRoomById(roomId);
|
||||
room.notSeen++;
|
||||
}
|
||||
|
||||
findRoomByOwner = (ownerId: number): Promise<{ room_id: number }[]> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const rooms = this.rooms.filter((room) => room.owner_id === ownerId);
|
||||
const res = [];
|
||||
rooms.forEach((room) => {
|
||||
res.push({ room_id: room.room_id });
|
||||
});
|
||||
resolve(res);
|
||||
});
|
||||
};
|
||||
|
||||
getAddresseId = (email: string, name?: string): Promise<number> => {
|
||||
const match = this.users.find((user) => user.user.mailbox + "@" + user.user.host == email);
|
||||
return new Promise((resolve, reject) => resolve(match?.id));
|
||||
};
|
||||
|
||||
getUserIdOfMailbox = (boxId: number): Promise<{ user_id: number }[]> => {
|
||||
return new Promise((resolve, rejects) => resolve([{ user_id: this.users[0].id }]));
|
||||
};
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user