From 65631f8e9ab9e88f33652509a34cda7ddfdef859 Mon Sep 17 00:00:00 2001 From: grimhilt Date: Wed, 5 Apr 2023 12:33:32 +0200 Subject: [PATCH] thread tests --- back/mails/saveMessage.ts | 14 +- back/test/mail/saveMessage-test.ts | 159 ++++++++++++-------- back/test/test-utils/db/test-saveMessage.ts | 30 ++-- 3 files changed, 126 insertions(+), 77 deletions(-) diff --git a/back/mails/saveMessage.ts b/back/mails/saveMessage.ts index dc1f06c..86d43cd 100644 --- a/back/mails/saveMessage.ts +++ b/back/mails/saveMessage.ts @@ -82,6 +82,7 @@ export default class RegisterMessageInApp { async registerMembers(roomId: number) { getAllMembers(this.messageId).then((res) => { + if (res.lenght == 0) return; const data = res[0].id.split(","); data.forEach(async (memberId: number) => { await registerMember(roomId, memberId); @@ -124,8 +125,8 @@ export default class RegisterMessageInApp { // todo room not lenght, reply to transfer ? roomId = room[0].room_id; let root_id = room[0].root_id; - if (!root_id) root_id = roomId; - await registerThread(threadId, room[0].room_id, root_id); + if (root_id === undefined) root_id = roomId; + await registerThread(threadId, roomId, root_id); }); // impl register previous message or go back await registerMessageInRoom(this.messageId, threadId, this.envelope.date); @@ -150,7 +151,7 @@ export default class RegisterMessageInApp { await this.init(); if (this.envelope.inReplyTo) { this.inReplyTo = this.envelope.inReplyTo; - this.saveReply(); + await this.saveReply(); } else { if (await this.isFromUs()) { if (this.isDm()) { @@ -161,7 +162,7 @@ export default class RegisterMessageInApp { } 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); + await this.initiateRoom(this.ownerId, RoomType.ROOM); } } else { await this.createOrRegisterOnExistence(this.ownerId, RoomType.ROOM); @@ -181,7 +182,8 @@ export default class RegisterMessageInApp { if (isGroup) { this.createOrRegisterOnMembers(rooms[0].room_id); } else { - // reply from channel + // reply from CHANNEL or DM or ROOM + await this.initiateThread(); // todo // if (sender == owner) { // correction from the original sender // // leave in the same channel @@ -191,7 +193,7 @@ export default class RegisterMessageInApp { } else if (rooms.length > 1) { // get the lowest thread (order by room_id) const roomId = rooms[rooms.length - 1].room_id; - this.createOrRegisterOnMembers(roomId); + await this.createOrRegisterOnMembers(roomId); } }); } diff --git a/back/test/mail/saveMessage-test.ts b/back/test/mail/saveMessage-test.ts index c3ec76c..4956c9b 100644 --- a/back/test/mail/saveMessage-test.ts +++ b/back/test/mail/saveMessage-test.ts @@ -19,6 +19,7 @@ const boxId = 1; jest.mock("../../db/utils/mail", () => { return { + findRoomByOwner: jest.fn(), getAddresseId: jest.fn(), getUserIdOfMailbox: jest.fn(), }; @@ -37,7 +38,7 @@ jest.mock("../../db/saveMessage-db", () => { incrementNotSeenRoom: jest.fn(), }; }); -import { getAddresseId, getUserIdOfMailbox } from "../../db/utils/mail"; +import { getAddresseId, getUserIdOfMailbox, findRoomByOwner } from "../../db/utils/mail"; import { createRoom, registerMessageInRoom, @@ -50,6 +51,7 @@ import { getThreadInfo, incrementNotSeenRoom, } from "../../db/saveMessage-db"; +import { AttrsWithEnvelope } from "../../interfaces/mail/attrs.interface"; // todo esbuild // new message from us // to multiple people -> room @@ -67,9 +69,9 @@ import { // if only me reply -> channel beforeAll(async () => { - db.clear(); mocked(getAddresseId).mockImplementation(db.getAddresseId); mocked(getUserIdOfMailbox).mockImplementation(db.getUserIdOfMailbox); + mocked(findRoomByOwner).mockImplementation(db.findRoomByOwner); mocked(createRoom).mockImplementation(db.createRoom); mocked(registerMessageInRoom).mockImplementation(db.registerMessageInRoom); @@ -83,7 +85,30 @@ beforeAll(async () => { mocked(incrementNotSeenRoom).mockImplementation(db.incrementNotSeenRoom); }); + +const msgFromUs_1: { attrs: AttrsWithEnvelope; message_id: number } = { + attrs: generateAttrs({ from: [ownUser.user], to: [db.users[1].user], messageId: "1" }), + message_id: 1, +}; +const replyTo1_2: { attrs: AttrsWithEnvelope; message_id: number } = { + attrs: generateAttrs({ from: [ownUser.user], to: [db.users[1].user], messageId: "2", inReplyTo: "1" }), + message_id: 2, +}; + +const replyTo2_3: { attrs: AttrsWithEnvelope; message_id: number } = { + attrs: generateAttrs({ from: [ownUser.user], to: [db.users[1].user, db.users[2].user], messageId: "3", inReplyTo: "2" }), + message_id: 3, +}; + +beforeEach(async () => { + db.clear(); + db.messages.push(msgFromUs_1); + db.messages.push(replyTo1_2); + db.messages.push(replyTo2_3); +}); + describe("saveMessage", () => { + describe("functions", () => { it("isFromUs", async () => { const attrs = generateAttrs({ from: [ownUser.user], to: [db.users[1].user] }); @@ -101,79 +126,93 @@ describe("saveMessage", () => { expect(res2).toBe(false); }); }); - describe("implementation", () => { - describe("new first message from us", () => { - it("should create a DM when there is a new first message from us to one recipient", async () => { - const attrs = generateAttrs({ from: [ownUser.user], to: [db.users[1].user] }); + describe("room creation", () => { + it("should create a DM when there is a new first message from us to one recipient", async () => { + const attrs = generateAttrs({ from: [ownUser.user], to: [db.users[1].user] }); - const register = new registerMessageInApp(messageId, attrs, boxId); + const register = new registerMessageInApp(messageId, attrs, boxId); - const createOrRegisterOnExistence = jest - .spyOn(register, "createOrRegisterOnExistence") - .mockImplementation( - (owner: number, roomType: RoomType) => new Promise((resolve, reject) => resolve()), - ); + const createOrRegisterOnExistence = jest + .spyOn(register, "createOrRegisterOnExistence") + .mockImplementation((owner: number, roomType: RoomType) => new Promise((resolve, reject) => resolve())); - await register.save(); + await register.save(); - expect(createOrRegisterOnExistence).toHaveBeenCalledWith(db.users[1].id, RoomType.DM); - }); - it("should create a ROOM when there is a new first message from us to multiple recipients", async () => { - 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: RoomType) => Promise.resolve(1)); - - await register.save(); - - 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", () => { - - // }); + expect(createOrRegisterOnExistence).toHaveBeenCalledWith(db.users[1].id, RoomType.DM); }); - describe("new first message from other", () => { - it("should create a ROOM when there is a new first message from other to me only", async () => { - const attrs = generateAttrs({ from: [db.users[1].user], to: [ownUser.user] }); + it("should create a ROOM when there is a new first message from us to multiple recipients", async () => { + const attrs = generateAttrs({ from: [ownUser.user], to: [db.users[1].user, db.users[2].user] }); - const register = new registerMessageInApp(messageId, attrs, boxId); + const register = new registerMessageInApp(messageId, attrs, boxId); - const createOrRegisterOnExistence = jest - .spyOn(register, "createOrRegisterOnExistence") - .mockImplementation((owner: number, roomType: RoomType) => { - return new Promise((resolve, reject) => resolve()); - }); + const initiateRoom = jest + .spyOn(register, "initiateRoom") + .mockImplementation((owner: number, roomType: RoomType) => Promise.resolve(1)); - await register.save(); + await register.save(); - expect(createOrRegisterOnExistence).toHaveBeenCalledWith(db.users[1].id, RoomType.ROOM); - }); + expect(initiateRoom).toHaveBeenCalledWith(ownUser.id, RoomType.ROOM); }); - describe("replies", () => { - it("", () => {}); + // 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", () => { + + // }); + it("should create a ROOM when there is a new first message from other to me only", async () => { + 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: RoomType) => { + return new Promise((resolve, reject) => resolve()); + }); + + await register.save(); + + expect(createOrRegisterOnExistence).toHaveBeenCalledWith(db.users[1].id, RoomType.ROOM); }); + it("should create THREAD when reply to a message in a DM", async () => { + let register = new registerMessageInApp(msgFromUs_1.message_id, msgFromUs_1.attrs, boxId); + await register.save(); + register = new registerMessageInApp(replyTo1_2.message_id, replyTo1_2.attrs, boxId); + await register.save(); + + const thread = db.rooms.find((room) => room.is_thread) + expect(thread.room_type).toBe(RoomType.THREAD); + expect(thread.root_id).toBe(0); + expect(thread.parent_id).toBe(0); + }); + + it("should create THREAD when reply in THREAD with different members", async() => { + let register = new registerMessageInApp(msgFromUs_1.message_id, msgFromUs_1.attrs, boxId); + await register.save(); + register = new registerMessageInApp(replyTo1_2.message_id, replyTo1_2.attrs, boxId); + await register.save(); + register = new registerMessageInApp(replyTo2_3.message_id, replyTo2_3.attrs, boxId); + await register.save(); + + const threads = db.rooms.filter((room) => room.is_thread); + expect(threads).toHaveLength(2); + const thread = threads[1]; + expect(thread.room_type).toBe(RoomType.THREAD); + expect(thread.root_id).toBe(0); + expect(thread.parent_id).toBe(1); + expect(thread.members).toHaveLength(3); + }); + }); + describe("replies", () => { + it("", () => {}); }); describe("unseen behavior", () => { - it("should add unseen in room when a message creates a room", () => { - - }); + it("should add unseen in room when a message creates a room", () => {}); - it("should add unseen in room when a message joins a room", () => { - - }); + it("should add unseen in room when a message joins a room", () => {}); - it("should add unseen in root room and thread when new message creates a thread", () => { - - }); + it("should add unseen in root room and thread when new message creates a thread", () => {}); - it("should add unseen in root room and thread when new message joins in thread", () => { - - }); + it("should add unseen in root room and thread when new message joins in thread", () => {}); }); }); diff --git a/back/test/test-utils/db/test-saveMessage.ts b/back/test/test-utils/db/test-saveMessage.ts index 79e75e2..9ec47fa 100644 --- a/back/test/test-utils/db/test-saveMessage.ts +++ b/back/test/test-utils/db/test-saveMessage.ts @@ -36,14 +36,15 @@ export default class saveMessageDatabase { clear() { this.rooms = []; this.messages = []; + this.room_message = []; this.roomId = 0; } - _findRoomById(roomId: number): Room { + _findRoomById = (roomId: number): Room => { return this.rooms.find((room) => room.room_id === roomId); } - _findUserByMailbox(mailbox: string): UserTest { + _findUserByMailbox = (mailbox: string): UserTest => { return this.users.find((user) => user.user.mailbox === mailbox); } @@ -71,7 +72,7 @@ export default class saveMessageDatabase { return Promise.resolve(); }; - isRoomGroup(roomId: number): Promise { + isRoomGroup = (roomId: number): Promise => { return new Promise((resolve, reject) => { resolve(this.rooms.find((room) => room.room_id == roomId).room_type === RoomType.GROUP); }); @@ -88,7 +89,7 @@ export default class saveMessageDatabase { }); }; - hasSameMembersAsParent(messageId: number, messageID: string): Promise { + hasSameMembersAsParent = (messageId: number, messageID: string): Promise => { const msg1 = this.messages.find((message) => message.attrs.envelope.messageId === messageID ); const msg2 = this.messages.find((message) => message.message_id === messageId ); const members1 = getMembers(msg1.attrs.envelope); @@ -102,19 +103,26 @@ export default class saveMessageDatabase { registerThread = async (roomId: number, parentId: number, rootId: number) => { const room = this._findRoomById(roomId); + room.is_thread = true; room.parent_id = parentId; - room.room_id = rootId; + room.root_id = rootId; }; - registerMember(roomId: number, memberId: number): Promise { + registerMember = (roomId: number, memberId: number): Promise => { const room = this._findRoomById(roomId); - room.members.push(this.users.find((user) => user.id === memberId)); + if (!room.members) room.members = []; + room.members.push(this.users.find((user) => user.id == memberId)); return Promise.resolve(true); } - getAllMembers(messageId: number): Promise { - // test_todo - return Promise.resolve(true); + getAllMembers = (messageId: number): Promise => { + const message = this.messages.find((message) => message.message_id === messageId); + let res = ""; + getMembers(message.attrs.envelope).forEach((member) => { + res += this.users.find((user) => user.user.mailbox === member.mailbox).id + ","; + }); + res = res.substring(0, res.length-1); + return Promise.resolve([{id: res}]); } getThreadInfo = (messageID: string): Promise<{ room_id: number; root_id: number }[]> => { @@ -126,7 +134,7 @@ export default class saveMessageDatabase { incrementNotSeenRoom = (roomId: number): Promise => { const room = this._findRoomById(roomId); - room.notSeen++; + if (room) room.notSeen++; // todo return Promise.resolve(); };