From cfc0a0b0f530808bf417010e657957c063016c3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=83=87=E3=83=AF=E3=83=B3=E3=82=B7=E3=83=A5?= <61188295+Dnouv@users.noreply.github.com> Date: Tue, 16 Apr 2024 04:45:38 +0530 Subject: [PATCH] feat: Implement the Apps Engine Room message read bridge (#753) --- src/definition/accessors/IRoomRead.ts | 19 +++++++++++++++---- src/server/accessors/RoomRead.ts | 11 +++++++++-- src/server/bridges/RoomBridge.ts | 24 ++++++++++++++++++++++++ tests/server/accessors/RoomRead.spec.ts | 11 ++++++++++- tests/test-data/bridges/roomBridge.ts | 4 ++++ 5 files changed, 62 insertions(+), 7 deletions(-) diff --git a/src/definition/accessors/IRoomRead.ts b/src/definition/accessors/IRoomRead.ts index 58e0583c7..4e827507d 100644 --- a/src/definition/accessors/IRoomRead.ts +++ b/src/definition/accessors/IRoomRead.ts @@ -40,12 +40,23 @@ export interface IRoomRead { getCreatorUserByName(name: string): Promise; /** - * Gets an iterator for all of the messages in the provided room. + * Retrieves an array of messages from the specified room. * - * @param roomId the room's id - * @returns an iterator for messages + * @param roomId The unique identifier of the room from which to retrieve messages. + * @param options Optional parameters for retrieving messages: + * - limit: The maximum number of messages to retrieve. If more than 100 is passed, it defaults to 100. + * - skip: The number of messages to skip (for pagination). + * - sort: An object defining the sorting order of the messages. Each key is a field to sort by, and the value is either 1 for ascending order or -1 for descending order. + * @returns A Promise that resolves to an array of IMessage objects representing the messages in the room. */ - getMessages(roomId: string): Promise>; + getMessages( + roomId: string, + options?: Partial<{ + limit: number; + skip: number; + sort: Record; + }>, + ): Promise; /** * Gets an iterator for all of the users in the provided room. diff --git a/src/server/accessors/RoomRead.ts b/src/server/accessors/RoomRead.ts index da4273f53..d79a64028 100644 --- a/src/server/accessors/RoomRead.ts +++ b/src/server/accessors/RoomRead.ts @@ -23,8 +23,15 @@ export class RoomRead implements IRoomRead { return this.roomBridge.doGetCreatorByName(name, this.appId); } - public getMessages(roomId: string): Promise> { - throw new Error('Method not implemented.'); + public getMessages( + roomId: string, + options?: Partial<{ + limit: number; + skip: number; + sort: Record; + }>, + ): Promise { + return this.roomBridge.doGetMessages(roomId, { limit: 100, ...options }, this.appId); } public getMembers(roomId: string): Promise> { diff --git a/src/server/bridges/RoomBridge.ts b/src/server/bridges/RoomBridge.ts index 677620283..a1ec60952 100644 --- a/src/server/bridges/RoomBridge.ts +++ b/src/server/bridges/RoomBridge.ts @@ -91,6 +91,20 @@ export abstract class RoomBridge extends BaseBridge { } } + public async doGetMessages( + roomId: string, + options: { + limit: number; + skip?: number; + sort?: Record; + }, + appId: string, + ): Promise { + if (this.hasReadPermission(appId)) { + return this.getMessages(roomId, options, appId); + } + } + protected abstract create(room: IRoom, members: Array, appId: string): Promise; protected abstract getById(roomId: string, appId: string): Promise; @@ -123,6 +137,16 @@ export abstract class RoomBridge extends BaseBridge { protected abstract getLeaders(roomId: string, appId: string): Promise>; + protected abstract getMessages( + roomId: string, + options: { + limit: number; + skip?: number; + sort?: Record; + }, + appId: string, + ): Promise; + private hasWritePermission(appId: string): boolean { if (AppPermissionManager.hasPermission(appId, AppPermissions.room.write)) { return true; diff --git a/tests/server/accessors/RoomRead.spec.ts b/tests/server/accessors/RoomRead.spec.ts index 5d2a142c5..f99eae19e 100644 --- a/tests/server/accessors/RoomRead.spec.ts +++ b/tests/server/accessors/RoomRead.spec.ts @@ -5,21 +5,26 @@ import type { IUser } from '../../../src/definition/users'; import { RoomRead } from '../../../src/server/accessors'; import type { RoomBridge } from '../../../src/server/bridges'; import { TestData } from '../../test-data/utilities'; +import type { IMessage } from '../../../src/definition/messages'; export class RoomReadAccessorTestFixture { private room: IRoom; private user: IUser; + private messages: IMessage[]; + private mockRoomBridgeWithRoom: RoomBridge; @SetupFixture public setupFixture() { this.room = TestData.getRoom(); this.user = TestData.getUser(); + this.messages = ['507f1f77bcf86cd799439011', '507f191e810c19729de860ea'].map((id) => TestData.getMessage(id)); const theRoom = this.room; const theUser = this.user; + const theMessages = this.messages; this.mockRoomBridgeWithRoom = { doGetById(id, appId): Promise { return Promise.resolve(theRoom); @@ -39,6 +44,9 @@ export class RoomReadAccessorTestFixture { doGetMembers(name, appId): Promise> { return Promise.resolve([theUser]); }, + doGetMessages(roomId, appId, options): Promise { + return Promise.resolve(theMessages); + }, } as RoomBridge; } @@ -58,6 +66,8 @@ export class RoomReadAccessorTestFixture { Expect(await rr.getCreatorUserByName('testing')).toBe(this.user); Expect(await rr.getDirectByUsernames([this.user.username])).toBeDefined(); Expect(await rr.getDirectByUsernames([this.user.username])).toBe(this.room); + Expect(await rr.getMessages('testing')).toBeDefined(); + Expect(await rr.getMessages('testing')).toBe(this.messages); } @AsyncTest() @@ -65,7 +75,6 @@ export class RoomReadAccessorTestFixture { Expect(() => new RoomRead(this.mockRoomBridgeWithRoom, 'testing-app')).not.toThrow(); const rr = new RoomRead(this.mockRoomBridgeWithRoom, 'testing-app'); - await Expect(() => rr.getMessages('faker')).toThrowErrorAsync(Error, 'Method not implemented.'); Expect(await rr.getMembers('testing')).toBeDefined(); Expect((await rr.getMembers('testing')) as Array).not.toBeEmpty(); diff --git a/tests/test-data/bridges/roomBridge.ts b/tests/test-data/bridges/roomBridge.ts index c25edbb4f..92a596f8e 100644 --- a/tests/test-data/bridges/roomBridge.ts +++ b/tests/test-data/bridges/roomBridge.ts @@ -32,6 +32,10 @@ export class TestsRoomBridge extends RoomBridge { throw new Error('Method not implemented.'); } + public getMessages(roomId: string, options: { limit: number; skip?: number; sort?: Record }, appId: string): Promise { + throw new Error('Method not implemented.'); + } + public update(room: IRoom, members: Array, appId: string): Promise { throw new Error('Method not implemented.'); }