use wiremock::ResponseTemplate; use crate::helpers::{TestApp, fake_newsletter_body, fake_post_body, when_sending_an_email}; #[tokio::test] async fn subscriber_can_unsubscribe() { let app = TestApp::spawn().await; app.create_confirmed_subscriber().await; app.admin_login().await; when_sending_an_email() .respond_with(ResponseTemplate::new(200)) .expect(1) .mount(&app.email_server) .await; app.post_newsletters(&fake_newsletter_body()).await; app.dispatch_all_pending_emails().await; let record = sqlx::query!("SELECT unsubscribe_token FROM subscriptions") .fetch_one(&app.connection_pool) .await .expect("Failed to fetch saved token"); let response = app .get_unsubscribe( record .unsubscribe_token .expect("Confirmed subscriber should have a valid unsubscribe token"), ) .await; assert_eq!(response.status().as_u16(), 200); let html_fragment = response.text().await.unwrap(); assert!(html_fragment.contains("Good bye, old friend")); let record = sqlx::query!("SELECT email FROM subscriptions") .fetch_optional(&app.connection_pool) .await .expect("Failed to fetch subscription table"); assert!(record.is_none()); when_sending_an_email() .respond_with(ResponseTemplate::new(200)) .expect(0) .mount(&app.email_server) .await; app.post_newsletters(&fake_newsletter_body()).await; app.dispatch_all_pending_emails().await; } #[tokio::test] async fn a_valid_unsubscribe_link_is_present_in_new_post_email_notifications() { let app = TestApp::spawn().await; app.create_confirmed_subscriber().await; app.admin_login().await; when_sending_an_email() .respond_with(ResponseTemplate::new(200)) .expect(1) .mount(&app.email_server) .await; app.post_create_post(&fake_post_body()).await; app.dispatch_all_pending_emails().await; let email_request = app .email_server .received_requests() .await .unwrap() .pop() .unwrap(); let unsubscribe_links = app.get_unsubscribe_links(&email_request); reqwest::get(unsubscribe_links.html) .await .unwrap() .error_for_status() .unwrap(); let record = sqlx::query!("SELECT email FROM subscriptions") .fetch_optional(&app.connection_pool) .await .expect("Failed to fetch subscription table"); assert!(record.is_none()); } #[tokio::test] async fn a_valid_unsubscribe_link_is_present_in_emails_manually_sent() { let app = TestApp::spawn().await; app.create_confirmed_subscriber().await; app.admin_login().await; when_sending_an_email() .respond_with(ResponseTemplate::new(200)) .expect(1) .mount(&app.email_server) .await; app.post_newsletters(&fake_newsletter_body()).await; app.dispatch_all_pending_emails().await; let email_request = app .email_server .received_requests() .await .unwrap() .pop() .unwrap(); let unsubscribe_links = app.get_unsubscribe_links(&email_request); reqwest::get(unsubscribe_links.html) .await .unwrap() .error_for_status() .unwrap(); } #[tokio::test] async fn an_invalid_unsubscribe_token_is_rejected() { let app = TestApp::spawn().await; app.create_confirmed_subscriber().await; let response = reqwest::get(format!("{}/unsubscribe?token=invalid", app.address)) .await .unwrap(); assert_eq!(response.status().as_u16(), 404); }