Skip to content

Commit

Permalink
Merge branch 'develop' into chore/useAppUiKitInteraction
Browse files Browse the repository at this point in the history
  • Loading branch information
ggazzo committed Sep 5, 2024
2 parents 4d8ba8f + 532f088 commit 9d66f42
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 4 deletions.
7 changes: 7 additions & 0 deletions .changeset/quiet-cherries-punch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@rocket.chat/meteor": minor
"@rocket.chat/core-services": minor
"@rocket.chat/rest-typings": minor
---

Return `parent` and `team` information when calling `rooms.info` endpoint
16 changes: 14 additions & 2 deletions apps/meteor/app/api/server/v1/rooms.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Media } from '@rocket.chat/core-services';
import { Media, Team } from '@rocket.chat/core-services';
import type { IRoom, IUpload } from '@rocket.chat/core-typings';
import { Messages, Rooms, Users, Uploads, Subscriptions } from '@rocket.chat/models';
import type { Notifications } from '@rocket.chat/rest-typings';
Expand Down Expand Up @@ -417,7 +417,19 @@ API.v1.addRoute(
return API.v1.failure('not-allowed', 'Not Allowed');
}

return API.v1.success({ room: (await Rooms.findOneByIdOrName(room._id, { projection: fields })) ?? undefined });
const discussionParent =
room.prid &&
(await Rooms.findOneById<Pick<IRoom, 'name' | 'fname' | 't' | 'prid' | 'u'>>(room.prid, {
projection: { name: 1, fname: 1, t: 1, prid: 1, u: 1 },
}));
const { team, parentRoom } = await Team.getRoomInfo(room);
const parent = discussionParent || parentRoom;

return API.v1.success({
room: (await Rooms.findOneByIdOrName(room._id, { projection: fields })) ?? undefined,
...(team && { team }),
...(parent && { parent }),
});
},
},
);
Expand Down
25 changes: 25 additions & 0 deletions apps/meteor/server/services/team/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type {
ITeam,
ITeamMember,
ITeamStats,
AtLeast,
} from '@rocket.chat/core-typings';
import type { InsertionModel } from '@rocket.chat/model-typings';
import { Team, Rooms, Subscriptions, Users, TeamMember } from '@rocket.chat/models';
Expand Down Expand Up @@ -1053,4 +1054,28 @@ export class TeamService extends ServiceClassInternal implements ITeamService {

return rooms;
}

private getParentRoom(team: AtLeast<ITeam, 'roomId'>): Promise<Pick<IRoom, 'name' | 'fname' | 't' | '_id'> | null> {
return Rooms.findOneById<Pick<IRoom, 'name' | 'fname' | 't' | '_id'>>(team.roomId, { projection: { name: 1, fname: 1, t: 1 } });
}

async getRoomInfo(
room: AtLeast<IRoom, 'teamId' | 'teamMain' | '_id'>,
): Promise<{ team?: Pick<ITeam, 'name' | 'roomId' | 'type'>; parentRoom?: Pick<IRoom, 'name' | 'fname' | 't' | '_id'> }> {
if (!room.teamId) {
return {};
}

const team = await Team.findOneById(room.teamId, { projection: { _id: 1, name: 1, roomId: 1, type: 1 } });
if (!team) {
return {};
}

if (room.teamMain) {
return { team };
}

const parentRoom = await this.getParentRoom(team);
return { team, ...(parentRoom && { parentRoom }) };
}
}
158 changes: 157 additions & 1 deletion apps/meteor/tests/end-to-end/api/rooms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1264,8 +1264,164 @@ describe('[Rooms]', () => {
})
.end(done);
});
});

it('should not return parent & team for room thats not on a team nor is a discussion', async () => {
await request
.get(api('rooms.info'))
.set(credentials)
.query({
roomId: testChannel._id,
})
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('room').and.to.be.an('object');
expect(res.body.room).to.not.have.property('team');
expect(res.body.room).to.not.have.property('prid');
});
});

describe('with team and parent data', () => {
const testChannelName = `channel.test.${Date.now()}-${Math.random()}`;
const teamName = `test-team-${Date.now()}`;
const discussionName = `test-discussion-${Date.now()}`;
const testChannelOutsideTeamname = `channel.test.outside.${Date.now()}-${Math.random()}`;
let testChannel: IRoom;
let testDiscussion: IRoom;
let testDiscussionMainRoom: IRoom;
let testTeam: ITeam;
let testChannelOutside: IRoom;
let testDiscussionOutsideTeam: IRoom;

before(async () => {
testChannel = (await createRoom({ type: 'c', name: testChannelName })).body.channel;

const teamResponse = await request.post(api('teams.create')).set(credentials).send({ name: teamName, type: 1 }).expect(200);
testTeam = teamResponse.body.team;

const resDiscussion = await request.post(api('rooms.createDiscussion')).set(credentials).send({
prid: testChannel._id,
t_name: discussionName,
});
testDiscussion = resDiscussion.body.discussion;

testDiscussionMainRoom = (
await request
.post(api('rooms.createDiscussion'))
.set(credentials)
.send({
prid: testTeam.roomId,
t_name: `test-discussion-${Date.now()}-team`,
})
).body.discussion;

await request
.post(api('teams.addRooms'))
.set(credentials)
.send({ rooms: [testChannel._id], teamId: testTeam._id });
});

before(async () => {
testChannelOutside = (await createRoom({ type: 'c', name: testChannelOutsideTeamname })).body.channel;
testDiscussionOutsideTeam = (
await request
.post(api('rooms.createDiscussion'))
.set(credentials)
.send({
prid: testChannelOutside._id,
t_name: `test-discussion-${Date.now()}`,
})
).body.discussion;
});

after(() =>
Promise.all([
deleteRoom({ type: 'c', roomId: testChannel._id }),
deleteRoom({ type: 'p', roomId: testDiscussion._id }),
deleteRoom({ type: 'c', roomId: testChannelOutside._id }),
deleteRoom({ type: 'p', roomId: testDiscussionOutsideTeam._id }),
deleteRoom({ type: 'p', roomId: testDiscussionMainRoom._id }),
deleteTeam(credentials, teamName),
]),
);

it('should return the channel info, team and parent info', async () => {
const result = await request.get(api('rooms.info')).set(credentials).query({ roomId: testChannel._id }).expect(200);

expect(result.body).to.have.property('success', true);
expect(result.body).to.have.property('team');
expect(result.body).to.have.property('parent');
expect(result.body.parent).to.have.property('_id').and.to.equal(testTeam.roomId);
});

it('should return the dicsussion room info and parent info', async () => {
await request
.get(api('rooms.info'))
.set(credentials)
.query({ roomId: testDiscussion._id })
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('parent').and.to.be.an('object');
expect(res.body.parent).to.have.property('_id').and.to.be.equal(testChannel._id);
});
});

it('should not return parent info for the main room of the team', async () => {
await request
.get(api('rooms.info'))
.set(credentials)
.query({ roomId: testTeam.roomId })
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.not.have.property('parent');
expect(res.body).to.have.property('team');
});
});

it('should not return team for room outside team', async () => {
await request
.get(api('rooms.info'))
.set(credentials)
.query({ roomId: testChannelOutside._id })
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.not.have.property('team');
expect(res.body).to.not.have.property('parent');
});
});

it('should return the parent for discussion outside team', async () => {
await request
.get(api('rooms.info'))
.set(credentials)
.query({ roomId: testDiscussionOutsideTeam._id })
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('parent').and.to.be.an('object');
expect(res.body.parent).to.have.property('_id').and.to.be.equal(testChannelOutside._id);
expect(res.body).to.not.have.property('team');
});
});

it('should return the parent for a discussion created from team main room', async () => {
await request
.get(api('rooms.info'))
.set(credentials)
.query({ roomId: testDiscussionMainRoom._id })
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('parent').and.to.be.an('object');
expect(res.body.parent).to.have.property('_id').and.to.be.equal(testTeam.roomId);
expect(res.body).to.not.have.property('team');
});
});
});
});
describe('[/rooms.leave]', () => {
let testChannel: IRoom;
let testGroup: IRoom;
Expand Down
4 changes: 4 additions & 0 deletions packages/core-services/src/types/ITeamService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {
IRoom,
IUser,
IRole,
AtLeast,
} from '@rocket.chat/core-typings';
import type { Document, Filter, FindOptions } from 'mongodb';

Expand Down Expand Up @@ -125,4 +126,7 @@ export interface ITeamService {
getStatistics(): Promise<ITeamStats>;
findBySubscribedUserIds(userId: string, callerId?: string): Promise<ITeam[]>;
addRolesToMember(teamId: string, userId: string, roles: Array<string>): Promise<boolean>;
getRoomInfo(
room: AtLeast<IRoom, 'teamId' | 'teamMain' | '_id'>,
): Promise<{ team?: Pick<ITeam, 'name' | 'roomId' | 'type'>; parentRoom?: Pick<IRoom, 'name' | 'fname' | 't' | '_id'> }>;
}
4 changes: 3 additions & 1 deletion packages/rest-typings/src/v1/rooms.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { IMessage, IRoom, IUser, RoomAdminFieldsType, IUpload, IE2EEMessage } from '@rocket.chat/core-typings';
import type { IMessage, IRoom, IUser, RoomAdminFieldsType, IUpload, IE2EEMessage, ITeam } from '@rocket.chat/core-typings';

import type { PaginatedRequest } from '../helpers/PaginatedRequest';
import type { PaginatedResult } from '../helpers/PaginatedResult';
Expand Down Expand Up @@ -626,6 +626,8 @@ export type RoomsEndpoints = {
'/v1/rooms.info': {
GET: (params: RoomsInfoProps) => {
room: IRoom | undefined;
parent?: Pick<IRoom, '_id' | 'name' | 'fname' | 't' | 'prid' | 'u'>;
team?: Pick<ITeam, 'name' | 'roomId' | 'type' | '_id'>;
};
};

Expand Down

0 comments on commit 9d66f42

Please sign in to comment.