Files
banner/tests/admin_rmp.rs

103 lines
3.4 KiB
Rust

mod helpers;
use banner::data::rmp::unmatch_instructor;
use sqlx::PgPool;
/// Test that unmatching an instructor resets accepted candidates back to pending.
///
/// When a user unmatches an instructor, accepted candidates should be reset to
/// 'pending' so they can be re-matched later. This prevents the bug where
/// candidates remain 'accepted' but have no corresponding link.
#[sqlx::test]
async fn unmatch_resets_accepted_candidates_to_pending(pool: PgPool) {
// ARRANGE: Create an instructor
let (instructor_id,): (i32,) = sqlx::query_as(
"INSERT INTO instructors (display_name, email)
VALUES ('Test, Instructor', 'test@utsa.edu')
RETURNING id",
)
.fetch_one(&pool)
.await
.expect("failed to create instructor");
// ARRANGE: Create an RMP professor
let (rmp_legacy_id,): (i32,) = sqlx::query_as(
"INSERT INTO rmp_professors (legacy_id, graphql_id, first_name, last_name, num_ratings)
VALUES (9999999, 'test-graphql-id', 'Test', 'Professor', 10)
RETURNING legacy_id",
)
.fetch_one(&pool)
.await
.expect("failed to create rmp professor");
// ARRANGE: Create a match candidate with 'accepted' status
sqlx::query(
"INSERT INTO rmp_match_candidates (instructor_id, rmp_legacy_id, score, status)
VALUES ($1, $2, 0.85, 'accepted')",
)
.bind(instructor_id)
.bind(rmp_legacy_id)
.execute(&pool)
.await
.expect("failed to create candidate");
// ARRANGE: Create a link in instructor_rmp_links
sqlx::query(
"INSERT INTO instructor_rmp_links (instructor_id, rmp_legacy_id, source)
VALUES ($1, $2, 'manual')",
)
.bind(instructor_id)
.bind(rmp_legacy_id)
.execute(&pool)
.await
.expect("failed to create link");
// ARRANGE: Update instructor status to 'confirmed'
sqlx::query("UPDATE instructors SET rmp_match_status = 'confirmed' WHERE id = $1")
.bind(instructor_id)
.execute(&pool)
.await
.expect("failed to update instructor status");
// ACT: Unmatch the specific RMP profile
unmatch_instructor(&pool, instructor_id, Some(rmp_legacy_id))
.await
.expect("unmatch should succeed");
// ASSERT: Candidate should be reset to pending
let (candidate_status,): (String,) = sqlx::query_as(
"SELECT status FROM rmp_match_candidates
WHERE instructor_id = $1 AND rmp_legacy_id = $2",
)
.bind(instructor_id)
.bind(rmp_legacy_id)
.fetch_one(&pool)
.await
.expect("failed to fetch candidate status");
assert_eq!(
candidate_status, "pending",
"candidate should be reset to pending after unmatch"
);
// ASSERT: Link should be deleted
let (link_count,): (i64,) =
sqlx::query_as("SELECT COUNT(*) FROM instructor_rmp_links WHERE instructor_id = $1")
.bind(instructor_id)
.fetch_one(&pool)
.await
.expect("failed to count links");
assert_eq!(link_count, 0, "link should be deleted");
// ASSERT: Instructor status should be unmatched
let (instructor_status,): (String,) =
sqlx::query_as("SELECT rmp_match_status FROM instructors WHERE id = $1")
.bind(instructor_id)
.fetch_one(&pool)
.await
.expect("failed to fetch instructor status");
assert_eq!(
instructor_status, "unmatched",
"instructor should be unmatched"
);
}