Skip to content

Commit 03709bc

Browse files
authored
Merge branch 'develop' into fix/error-priority
2 parents 74b7b27 + 511a59e commit 03709bc

File tree

3 files changed

+128
-49
lines changed

3 files changed

+128
-49
lines changed

.github/workflows/ci.yml

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -707,20 +707,21 @@ jobs:
707707
SRC="${{ steps.gh-docker.outputs.gh-image-name }}"
708708
DEST_REPO="docker.io/${IMAGE_NAME}"
709709
710-
# build --additional-tag for all other tags
711-
EXTRA_ARGS=()
710+
echo "Copying $SRC to ${DEST_REPO}:${PRIMARY}"
711+
skopeo copy --all \
712+
"docker://${SRC}" \
713+
"docker://${DEST_REPO}:${PRIMARY}"
714+
715+
# copy additional tags
712716
if (( ${#TAGS[@]} > 1 )); then
713717
for t in "${TAGS[@]:1}"; do
714-
EXTRA_ARGS+=( --additional-tag "${DEST_REPO}:${t}" )
718+
echo "Copying $SRC to ${DEST_REPO}:${t}"
719+
skopeo copy --all \
720+
"docker://${SRC}" \
721+
"docker://${DEST_REPO}:${t}"
715722
done
716723
fi
717724
718-
echo "Copying $SRC to ${DEST_REPO}:${PRIMARY} with extras ${EXTRA_ARGS[*]}"
719-
skopeo copy --all \
720-
"docker://${SRC}" \
721-
"docker://${DEST_REPO}:${PRIMARY}" \
722-
"${EXTRA_ARGS[@]}"
723-
724725
notify-services:
725726
name: 🚀 Notify external services
726727
runs-on: ubuntu-24.04

apps/meteor/tests/data/rooms.helper.ts

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { Credentials } from '@rocket.chat/api-client';
22
import type { IRoom, ISubscription } from '@rocket.chat/core-typings';
33

44
import { api, credentials, methodCall, request } from './api-data';
5+
import type { IRequestConfig } from './users.helper';
56

67
type CreateRoomParams = {
78
name?: IRoom['name'];
@@ -13,6 +14,7 @@ type CreateRoomParams = {
1314
credentials?: Credentials;
1415
extraData?: Record<string, any>;
1516
voipCallDirection?: 'inbound' | 'outbound';
17+
config?: IRequestConfig;
1618
};
1719

1820
export const createRoom = ({
@@ -25,22 +27,22 @@ export const createRoom = ({
2527
credentials: customCredentials,
2628
extraData,
2729
voipCallDirection = 'inbound',
30+
config,
2831
}: CreateRoomParams) => {
2932
if (!type) {
3033
throw new Error('"type" is required in "createRoom.ts" test helper');
3134
}
3235

36+
const requestInstance = config?.request || request;
37+
const credentialsInstance = config?.credentials || customCredentials || credentials;
38+
3339
if (type === 'v') {
3440
/* Special handling for voip type of rooms.
3541
* The endpoints below do not have a way to create
3642
* a voip room. Hence creation of a voip room
3743
* is handled separately here.
3844
*/
39-
return request
40-
.get(api('voip/room'))
41-
.query({ token, agentId, direction: voipCallDirection })
42-
.set(customCredentials || credentials)
43-
.send();
45+
return requestInstance.get(api('voip/room')).query({ token, agentId, direction: voipCallDirection }).set(credentialsInstance).send();
4446
}
4547

4648
if (type === 'd' && !username) {
@@ -58,9 +60,9 @@ export const createRoom = ({
5860
// which is the only case where type is not in the endpoints object
5961
const roomType = endpoints[type as keyof typeof endpoints];
6062

61-
return request
63+
return requestInstance
6264
.post(api(roomType))
63-
.set(customCredentials || credentials)
65+
.set(credentialsInstance)
6466
.send({
6567
...params,
6668
...(members && { members }),
@@ -120,18 +122,36 @@ export const getSubscriptionByRoomId = (roomId: IRoom['_id'], userCredentials =
120122
});
121123
});
122124

125+
/**
126+
* Adds users to a room using the addUsersToRoom method.
127+
*
128+
* Invites one or more users to join a room using the DDP method call.
129+
* Supports both local and federated users, with proper error handling
130+
* for federation restrictions.
131+
*
132+
* @param usernames - Array of usernames to add to the room
133+
* @param rid - The unique identifier of the room
134+
* @param userCredentials - Optional credentials for the request (deprecated, use config instead)
135+
* @param config - Optional request configuration for custom domains
136+
* @returns Promise resolving to the method call response
137+
*/
123138
export const addUserToRoom = ({
124139
usernames,
125140
rid,
126141
userCredentials,
142+
config,
127143
}: {
128144
usernames: string[];
129145
rid: IRoom['_id'];
130146
userCredentials?: Credentials;
147+
config?: IRequestConfig;
131148
}) => {
132-
return request
149+
const requestInstance = config?.request || request;
150+
const credentialsInstance = config?.credentials || userCredentials || credentials;
151+
152+
return requestInstance
133153
.post(methodCall('addUsersToRoom'))
134-
.set(userCredentials ?? credentials)
154+
.set(credentialsInstance)
135155
.send({
136156
message: JSON.stringify({
137157
method: 'addUsersToRoom',
Lines changed: 89 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,47 @@
11
import type { Credentials } from '@rocket.chat/api-client';
22
import type { IUser } from '@rocket.chat/core-typings';
33
import { UserStatus } from '@rocket.chat/core-typings';
4+
import supertest from 'supertest';
5+
import type { Response } from 'supertest';
46

57
import { api, credentials, methodCall, request } from './api-data';
68
import { password } from './user';
79

810
export type TestUser<TUser extends IUser> = TUser & { username: string; emails: string[] };
911

12+
/**
13+
* Configuration interface for custom request handling.
14+
*
15+
* Provides a way to override the default request instance and credentials
16+
* for testing scenarios that require custom domains or authentication.
17+
*/
18+
export interface IRequestConfig {
19+
credentials: Credentials;
20+
request: ReturnType<typeof supertest>;
21+
}
22+
23+
/**
24+
* Creates a request configuration for a specific domain.
25+
*
26+
* Sets up a new request instance and authenticates with the specified
27+
* domain, user, and password. This is essential for federation testing
28+
* where multiple Rocket.Chat instances need to be accessed.
29+
*
30+
* @param domain - The base URL of the Rocket.Chat instance
31+
* @param user - The username for authentication
32+
* @param password - The password for authentication
33+
* @returns Promise resolving to request configuration with credentials
34+
*/
35+
export async function getRequestConfig(domain: string, user: string, password: string): Promise<IRequestConfig> {
36+
const request = supertest(domain);
37+
const credentials = await login(user, password, { request, credentials: {} as Credentials });
38+
39+
return {
40+
credentials,
41+
request,
42+
};
43+
}
44+
1045
export const createUser = <TUser extends IUser>(
1146
userData: {
1247
username?: string;
@@ -20,92 +55,111 @@ export const createUser = <TUser extends IUser>(
2055
password?: string;
2156
freeSwitchExtension?: string;
2257
} = {},
58+
config?: IRequestConfig,
2359
) =>
2460
new Promise<TestUser<TUser>>((resolve, reject) => {
2561
const username = userData.username || `user.test.${Date.now()}.${Math.random()}`;
2662
const email = userData.email || `${username}@rocket.chat`;
27-
void request
63+
const requestInstance = config?.request || request;
64+
const credentialsInstance = config?.credentials || credentials;
65+
66+
void requestInstance
2867
.post(api('users.create'))
29-
.set(credentials)
68+
.set(credentialsInstance)
3069
.send({ email, name: username, username, password, ...userData })
3170
// if we don't expect 200, there's never an error, even in the case of a failure result
3271
.expect(200)
33-
.end((err, res) => {
72+
.end((err: unknown, res: Response) => {
3473
if (err) {
3574
return reject(err);
3675
}
3776
resolve(res.body.user);
3877
});
3978
});
4079

41-
export const login = (username: string | undefined, password: string): Promise<Credentials> =>
80+
export const login = (username: string | undefined, password: string, config?: IRequestConfig): Promise<Credentials> =>
4281
new Promise((resolve) => {
43-
void request
82+
const requestInstance = config?.request || request;
83+
void requestInstance
4484
.post(api('login'))
4585
.send({
4686
user: username,
4787
password,
4888
})
49-
.end((_err, res) => {
89+
.end((_err: unknown, res: Response) => {
5090
resolve({
5191
'X-Auth-Token': res.body.data.authToken,
5292
'X-User-Id': res.body.data.userId,
5393
});
5494
});
5595
});
5696

57-
export const deleteUser = async (user: Pick<IUser, '_id'>, extraData = {}) =>
58-
request
97+
export const deleteUser = async (user: Pick<IUser, '_id'>, extraData = {}, config?: IRequestConfig) => {
98+
const requestInstance = config?.request || request;
99+
const credentialsInstance = config?.credentials || credentials;
100+
return requestInstance
59101
.post(api('users.delete'))
60-
.set(credentials)
102+
.set(credentialsInstance)
61103
.send({
62104
userId: user._id,
63105
...extraData,
64106
});
107+
};
65108

66-
export const getUserByUsername = <TUser extends IUser>(username: string) =>
109+
export const getUserByUsername = <TUser extends IUser>(username: string, config?: IRequestConfig) =>
67110
new Promise<TestUser<TUser>>((resolve) => {
68-
void request
111+
const requestInstance = config?.request || request;
112+
const credentialsInstance = config?.credentials || credentials;
113+
114+
void requestInstance
69115
.get(api('users.info'))
70116
.query({ username })
71-
.set(credentials)
72-
.end((_err, res) => {
117+
.set(credentialsInstance)
118+
.end((_err: unknown, res: Response) => {
73119
resolve(res.body.user);
74120
});
75121
});
76122

77-
export const getMe = <TUser extends IUser>(overrideCredential = credentials) =>
123+
export const getMe = <TUser extends IUser>(overrideCredential = credentials, config?: IRequestConfig) =>
78124
new Promise<TestUser<TUser>>((resolve) => {
79-
void request
125+
const requestInstance = config?.request || request;
126+
const credentialsInstance = config?.credentials || overrideCredential;
127+
void requestInstance
80128
.get(api('me'))
81-
.set(overrideCredential)
129+
.set(credentialsInstance)
82130
.expect('Content-Type', 'application/json')
83131
.expect(200)
84-
.end((_end, res) => {
132+
.end((_end: unknown, res: Response) => {
85133
resolve(res.body);
86134
});
87135
});
88136

89-
export const setUserActiveStatus = (userId: IUser['_id'], activeStatus = true) =>
137+
export const setUserActiveStatus = (userId: IUser['_id'], activeStatus = true, config?: IRequestConfig) =>
90138
new Promise((resolve) => {
91-
void request
139+
const requestInstance = config?.request || request;
140+
const credentialsInstance = config?.credentials || credentials;
141+
142+
void requestInstance
92143
.post(api('users.setActiveStatus'))
93-
.set(credentials)
144+
.set(credentialsInstance)
94145
.send({
95146
userId,
96147
activeStatus,
97148
})
98149
.end(resolve);
99150
});
100151

101-
export const setUserStatus = (overrideCredentials = credentials, status = UserStatus.ONLINE) =>
102-
request.post(api('users.setStatus')).set(overrideCredentials).send({
152+
export const setUserStatus = (overrideCredentials = credentials, status = UserStatus.ONLINE, config?: IRequestConfig) => {
153+
const requestInstance = config?.request || request;
154+
return requestInstance.post(api('users.setStatus')).set(overrideCredentials).send({
103155
message: '',
104156
status,
105157
});
158+
};
106159

107-
export const setUserAway = (overrideCredentials = credentials) =>
108-
request
160+
export const setUserAway = (overrideCredentials = credentials, config?: IRequestConfig) => {
161+
const requestInstance = config?.request || request;
162+
return requestInstance
109163
.post(methodCall('UserPresence:away'))
110164
.set(overrideCredentials)
111165
.send({
@@ -116,9 +170,11 @@ export const setUserAway = (overrideCredentials = credentials) =>
116170
msg: 'method',
117171
}),
118172
});
173+
};
119174

120-
export const setUserOnline = (overrideCredentials = credentials) =>
121-
request
175+
export const setUserOnline = (overrideCredentials = credentials, config?: IRequestConfig) => {
176+
const requestInstance = config?.request || request;
177+
return requestInstance
122178
.post(methodCall('UserPresence:online'))
123179
.set(overrideCredentials)
124180
.send({
@@ -129,15 +185,17 @@ export const setUserOnline = (overrideCredentials = credentials) =>
129185
msg: 'method',
130186
}),
131187
});
188+
};
132189

133-
export const removeRoleFromUser = (username: string, roleId: string, overrideCredentials = credentials) =>
134-
getUserByUsername(username).then((user) =>
135-
request
190+
export const removeRoleFromUser = (username: string, roleId: string, overrideCredentials = credentials, config?: IRequestConfig) =>
191+
getUserByUsername(username, config).then((user) => {
192+
const requestInstance = config?.request || request;
193+
return requestInstance
136194
.post(api('users.update'))
137195
.set(overrideCredentials)
138196
.send({
139197
userId: user._id,
140198
data: { roles: user.roles.filter((role) => role !== roleId) },
141199
})
142-
.expect(200),
143-
);
200+
.expect(200);
201+
});

0 commit comments

Comments
 (0)