Skip to content

Commit 4bb6f24

Browse files
committed
Always allow requesting users directly
Allows `r? <user>` even if they are on a vacation or have full review capacity
1 parent b6e9fab commit 4bb6f24

File tree

2 files changed

+33
-70
lines changed

2 files changed

+33
-70
lines changed

src/handlers/assign.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -991,14 +991,16 @@ async fn candidate_reviewers_from_names<'a>(
991991
.any(|assignee| name_lower == assignee.login.to_lowercase());
992992

993993
let is_previously_assigned = previous_reviewer_names.contains(&name_lower);
994+
let is_directly_requested = reviewer_candidate.origin == ReviewerCandidateOrigin::Direct;
994995

995996
// Record the reason why the candidate was filtered out
996997
let reason = {
997998
if is_pr_author {
998999
Some(FindReviewerError::ReviewerIsPrAuthor {
9991000
username: candidate.clone(),
10001001
})
1001-
} else if is_on_vacation {
1002+
// Allow r? <user> even for people on a vacation
1003+
} else if is_on_vacation && !is_directly_requested {
10021004
Some(FindReviewerError::ReviewerOffRotation {
10031005
username: candidate.clone(),
10041006
})
@@ -1049,6 +1051,12 @@ async fn candidate_reviewers_from_names<'a>(
10491051
let candidate = candidate?;
10501052
let username = &candidate.name;
10511053

1054+
// If the reviewer was requested directly, do not consider their review preferences
1055+
let is_directly_requested = candidate.origin == ReviewerCandidateOrigin::Direct;
1056+
if is_directly_requested {
1057+
return Ok(candidate);
1058+
}
1059+
10521060
// If no review prefs were found, we assume the default unlimited
10531061
// review capacity and being on rotation.
10541062
let Some(review_prefs) = review_prefs.get(username.as_str()) else {

src/handlers/assign/tests/tests_candidates.rs

Lines changed: 24 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -162,18 +162,17 @@ async fn no_review_prefs() {
162162

163163
#[tokio::test]
164164
async fn at_max_capacity() {
165+
let teams = toml::toml!(compiler = ["martin", "diana"]);
165166
run_db_test(|ctx| async move {
166167
let user = user("martin", 1);
167168
review_prefs_test(ctx)
169+
.teams(&teams)
168170
.set_review_prefs(&user, Some(3), RotationMode::OnRotation)
169171
.await
170172
.assign_prs(user.id, 3)
171-
.check(
172-
&["martin"],
173-
Err(FindReviewerError::ReviewerAtMaxCapacity {
174-
username: "martin".to_string(),
175-
}),
176-
)
173+
.check(&["martin"], Ok(&["martin"]))
174+
.await?
175+
.check(&["compiler"], Ok(&["diana"]))
177176
.await
178177
})
179178
.await;
@@ -195,56 +194,53 @@ async fn below_max_capacity() {
195194

196195
#[tokio::test]
197196
async fn above_max_capacity() {
197+
let teams = toml::toml!(compiler = ["martin", "diana"]);
198198
run_db_test(|ctx| async move {
199199
let user = user("martin", 1);
200200
review_prefs_test(ctx)
201+
.teams(&teams)
201202
.set_review_prefs(&user, Some(3), RotationMode::OnRotation)
202203
.await
203204
.assign_prs(user.id, 10)
204-
.check(
205-
&["martin"],
206-
Err(FindReviewerError::ReviewerAtMaxCapacity {
207-
username: "martin".to_string(),
208-
}),
209-
)
205+
.check(&["martin"], Ok(&["martin"]))
206+
.await?
207+
.check(&["compiler"], Ok(&["diana"]))
210208
.await
211209
})
212210
.await;
213211
}
214212

215213
#[tokio::test]
216214
async fn max_capacity_zero() {
215+
let teams = toml::toml!(compiler = ["martin", "diana"]);
217216
run_db_test(|ctx| async move {
218217
let user = user("martin", 1);
219218
review_prefs_test(ctx)
219+
.teams(&teams)
220220
.set_review_prefs(&user, Some(0), RotationMode::OnRotation)
221221
.await
222222
.assign_prs(user.id, 0)
223-
.check(
224-
&["martin"],
225-
Err(FindReviewerError::ReviewerAtMaxCapacity {
226-
username: "martin".to_string(),
227-
}),
228-
)
223+
.check(&["martin"], Ok(&["martin"]))
224+
.await?
225+
.check(&["compiler"], Ok(&["diana"]))
229226
.await
230227
})
231228
.await;
232229
}
233230

234231
#[tokio::test]
235232
async fn ignore_username_case() {
233+
let teams = toml::toml!(compiler = ["martin", "diana"]);
236234
run_db_test(|ctx| async move {
237235
let user = user("MARtin", 1);
238236
review_prefs_test(ctx)
237+
.teams(&teams)
239238
.set_review_prefs(&user, Some(3), RotationMode::OnRotation)
240239
.await
241240
.assign_prs(user.id, 3)
242-
.check(
243-
&["MARTIN"],
244-
Err(FindReviewerError::ReviewerAtMaxCapacity {
245-
username: "MARTIN".to_string(),
246-
}),
247-
)
241+
.check(&["MARTIN"], Ok(&["MARTIN"]))
242+
.await?
243+
.check(&["compiler"], Ok(&["diana"]))
248244
.await
249245
})
250246
.await;
@@ -264,24 +260,6 @@ async fn unlimited_capacity() {
264260
.await;
265261
}
266262

267-
#[tokio::test]
268-
async fn ignore_user_off_rotation_direct() {
269-
run_db_test(|ctx| async move {
270-
let user = user("martin", 1);
271-
review_prefs_test(ctx)
272-
.set_review_prefs(&user, None, RotationMode::OffRotation)
273-
.await
274-
.check(
275-
&["martin"],
276-
Err(FindReviewerError::ReviewerOffRotation {
277-
username: "martin".to_string(),
278-
}),
279-
)
280-
.await
281-
})
282-
.await;
283-
}
284-
285263
#[tokio::test]
286264
async fn ignore_user_off_rotation_through_team() {
287265
run_db_test(|ctx| async move {
@@ -297,25 +275,6 @@ async fn ignore_user_off_rotation_through_team() {
297275
.await;
298276
}
299277

300-
#[tokio::test]
301-
async fn review_prefs_prefer_capacity_before_rotation() {
302-
run_db_test(|ctx| async move {
303-
let user = user("martin", 1);
304-
review_prefs_test(ctx)
305-
.set_review_prefs(&user, Some(1), RotationMode::OffRotation)
306-
.await
307-
.assign_prs(user.id, 2)
308-
.check(
309-
&["martin"],
310-
Err(FindReviewerError::ReviewerAtMaxCapacity {
311-
username: "martin".to_string(),
312-
}),
313-
)
314-
.await
315-
})
316-
.await;
317-
}
318-
319278
#[tokio::test]
320279
async fn multiple_reviewers() {
321280
run_db_test(|ctx| async move {
@@ -522,21 +481,17 @@ async fn invalid_org_doesnt_match() {
522481
}
523482

524483
#[tokio::test]
525-
async fn vacation() {
484+
async fn users_on_vacation() {
526485
let teams = toml::toml!(bootstrap = ["jyn514", "Mark-Simulacrum"]);
527486
let config = toml::toml!(users_on_vacation = ["jyn514"]);
528487

529488
run_db_test(|ctx| async move {
530-
// Test that `r? user` returns a specific error about the user being on vacation.
531489
basic_test(ctx, config, issue().call())
532490
.teams(&teams)
533-
.check(
534-
&["jyn514"],
535-
Err(FindReviewerError::ReviewerOffRotation {
536-
username: "jyn514".to_string(),
537-
}),
538-
)
491+
// Allow direct assignment
492+
.check(&["jyn514"], Ok(&["jyn514"]))
539493
.await?
494+
// But ignore the user when requesting a team
540495
.check(&["bootstrap"], Ok(&["Mark-Simulacrum"]))
541496
.await
542497
})

0 commit comments

Comments
 (0)