diff --git a/tests/api/subscriptions.rs b/tests/api/subscriptions.rs index 24e0796..d617fb5 100644 --- a/tests/api/subscriptions.rs +++ b/tests/api/subscriptions.rs @@ -1,4 +1,5 @@ use crate::helpers::spawn_app; +use reqwest::Url; use wiremock::matchers::{method, path}; use wiremock::{Mock, ResponseTemplate}; @@ -90,6 +91,52 @@ async fn subscribe_sends_a_confirmation_email_with_a_link() { assert_eq!(html_link, text_link); } +#[actix_rt::test] +async fn the_link_returned_by_subscribe_sets_a_subscriber_as_confirmed() { + // Arrange + let app = spawn_app().await; + let body = "name=le%20guin&email=ursula_le_guin%40gmail.com"; + + Mock::given(path("/email")) + .and(method("POST")) + .respond_with(ResponseTemplate::new(200)) + .mount(&app.email_server) + .await; + + app.post_subscriptions(body.into()).await; + let email_request = &app.email_server.received_requests().await.unwrap()[0]; + let body: serde_json::Value = serde_json::from_slice(&email_request.body).unwrap(); + + // Extract the link from one of the request fields. + let get_link = |s: &str| { + let links: Vec<_> = linkify::LinkFinder::new() + .links(s) + .filter(|l| *l.kind() == linkify::LinkKind::Url) + .collect(); + assert_eq!(links.len(), 1); + links[0].as_str().to_owned() + }; + let confirmation_link = Url::parse(&get_link(&body["HtmlBody"].as_str().unwrap())).unwrap(); + // Let's make sure we don't call random APIs on the web + assert_eq!(confirmation_link.domain().unwrap(), "127.0.0.1"); + + // Act + let response = reqwest::get(confirmation_link) + .await + .unwrap() + .error_for_status() + .unwrap(); + dbg!(&response); + + // Assert + let saved = sqlx::query!(r#"SELECT status FROM subscriptions WHERE name = 'le guin' AND email = 'ursula_le_guin@gmail.com'"#,) + .fetch_one(&app.db_pool) + .await + .expect("Failed to fetch saved subscription."); + + assert_eq!(saved.status, "confirmed"); +} + #[actix_rt::test] async fn subscribe_returns_a_400_when_data_is_missing() { // Arrange