|
1 | 1 | use crate::models::Crate;
|
| 2 | +use crate::schema::emails; |
2 | 3 | use crate::tests::builders::{CrateBuilder, PublishBuilder};
|
3 | 4 | use crate::tests::util::{
|
4 | 5 | MockAnonymousUser, MockCookieUser, MockTokenUser, RequestHelper, Response,
|
@@ -710,6 +711,54 @@ async fn test_decline_expired_invitation() {
|
710 | 711 | assert_eq!(json.users.len(), 1);
|
711 | 712 | }
|
712 | 713 |
|
| 714 | +/// Given a user inviting a different user to be a crate |
| 715 | +/// owner, check that the user invited cannot accept their |
| 716 | +/// invitation if they don't have a verified email address. |
| 717 | +#[tokio::test(flavor = "multi_thread")] |
| 718 | +async fn test_accept_invitation_without_verified_email() { |
| 719 | + let (app, anon, owner, owner_token) = TestApp::init().with_token().await; |
| 720 | + let mut conn = app.db_conn().await; |
| 721 | + let owner = owner.as_model(); |
| 722 | + |
| 723 | + // Create a user with a verified email (default behavior of db_new_user) |
| 724 | + let invited_user = app.db_new_user("user_unverified").await; |
| 725 | + |
| 726 | + // Update the email to be unverified |
| 727 | + diesel::update(emails::table) |
| 728 | + .filter(emails::user_id.eq(invited_user.as_model().id)) |
| 729 | + .set(emails::verified.eq(false)) |
| 730 | + .execute(&mut conn) |
| 731 | + .await |
| 732 | + .unwrap(); |
| 733 | + |
| 734 | + let krate = CrateBuilder::new("foo", owner.id) |
| 735 | + .expect_build(&mut conn) |
| 736 | + .await; |
| 737 | + |
| 738 | + // Invite the unverified user |
| 739 | + owner_token |
| 740 | + .add_named_owner("foo", "user_unverified") |
| 741 | + .await |
| 742 | + .good(); |
| 743 | + |
| 744 | + // Attempt to accept the invitation - this should fail |
| 745 | + let response = invited_user |
| 746 | + .try_accept_ownership_invitation::<()>(&krate.name, krate.id) |
| 747 | + .await; |
| 748 | + |
| 749 | + // Verify that the response is a 403 Forbidden with the expected error message |
| 750 | + assert_snapshot!(response.status(), @"403 Forbidden"); |
| 751 | + assert_snapshot!(response.text(), @r#"{"errors":[{"detail":"You need to verify your email address before you can accept the invitation to become an owner of the foo crate."}]}"#); |
| 752 | + |
| 753 | + // Verify that the invitation still exists |
| 754 | + let json = invited_user.list_invitations().await; |
| 755 | + assert_eq!(json.crate_owner_invitations.len(), 1); |
| 756 | + |
| 757 | + // Verify that the user is not listed as an owner |
| 758 | + let json = anon.show_crate_owners("foo").await; |
| 759 | + assert_eq!(json.users.len(), 1); |
| 760 | +} |
| 761 | + |
713 | 762 | #[tokio::test(flavor = "multi_thread")]
|
714 | 763 | async fn test_accept_expired_invitation_by_mail() {
|
715 | 764 | let (app, anon, owner, owner_token) = TestApp::init().with_token().await;
|
|
0 commit comments