use crate::helpers::{TestApp, fake_newsletter_body, fake_post_body, when_sending_an_email}; use wiremock::ResponseTemplate; #[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_confirm(&record.unsubscribe_token.unwrap()) .await; assert_eq!(response.status().as_u16(), 200); let html_fragment = response.text().await.unwrap(); assert!(html_fragment.contains("Good bye, 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_standalone_emails() { 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 = app.get_unsubscribe_confirm("invalid-token").await; // let response = reqwest::get(format!("{}/unsubscribe?token=invalid", app.address)) // .await // .unwrap(); assert_eq!(response.status().as_u16(), 404); } #[tokio::test] async fn subscription_works_after_unsubscribe() { let app = TestApp::spawn().await; app.create_confirmed_subscriber().await; let record = sqlx::query!("SELECT email, unsubscribe_token FROM subscriptions") .fetch_one(&app.connection_pool) .await .expect("Failed to fetch saved email and token"); let email = record.email; let response = app .get_unsubscribe_confirm(&record.unsubscribe_token.unwrap()) .await; assert_eq!(response.status().as_u16(), 200); let html_fragment = response.text().await.unwrap(); assert!(html_fragment.contains("Good bye, friend")); let record = sqlx::query!("SELECT email, unsubscribe_token FROM subscriptions") .fetch_optional(&app.connection_pool) .await .expect("Failed to fetch subscriber"); assert!(record.is_none()); when_sending_an_email() .respond_with(ResponseTemplate::new(200)) .expect(1) .mount(&app.email_server) .await; app.post_subscriptions(format!("email={}", email)).await; let requests = app.email_server.received_requests().await.unwrap(); let confirmation_request = requests.last().unwrap(); let confirmation_links = app.get_confirmation_links(confirmation_request); dbg!(&confirmation_links.html.as_str()); let response = reqwest::get(confirmation_links.html).await.unwrap(); assert_eq!(response.status().as_u16(), 200); assert!( response .text() .await .unwrap() .contains("Your email has been confirmed") ); let record = sqlx::query!("SELECT email, unsubscribe_token FROM subscriptions") .fetch_optional(&app.connection_pool) .await .expect("Failed to fetch subscriber"); assert!(record.is_some()); }