Get a 404.

This commit is contained in:
LukeMathWalker 2021-03-09 22:40:14 +00:00
parent 01f1d8758e
commit 967b16b19b
6 changed files with 25 additions and 8 deletions

View file

@ -1,4 +1,5 @@
application: application:
host: 127.0.0.1 host: 127.0.0.1
url: "http://127.0.0.1"
database: database:
require_ssl: false require_ssl: false

View file

@ -15,6 +15,7 @@ pub struct ApplicationSettings {
#[serde(deserialize_with = "deserialize_number_from_string")] #[serde(deserialize_with = "deserialize_number_from_string")]
pub port: u16, pub port: u16,
pub host: String, pub host: String,
pub url: String,
} }
#[derive(serde::Deserialize, Clone)] #[derive(serde::Deserialize, Clone)]

View file

@ -1,5 +1,6 @@
use crate::domain::{NewSubscriber, SubscriberEmail, SubscriberName}; use crate::domain::{NewSubscriber, SubscriberEmail, SubscriberName};
use crate::email_client::EmailClient; use crate::email_client::EmailClient;
use crate::startup::ApplicationUrl;
use actix_web::{web, HttpResponse}; use actix_web::{web, HttpResponse};
use chrono::Utc; use chrono::Utc;
use sqlx::PgPool; use sqlx::PgPool;
@ -24,7 +25,7 @@ impl TryInto<NewSubscriber> for FormData {
#[tracing::instrument( #[tracing::instrument(
name = "Adding a new subscriber", name = "Adding a new subscriber",
skip(form, pool, email_client), skip(form, pool, email_client, application_url),
fields( fields(
email = %form.email, email = %form.email,
name = %form.name name = %form.name
@ -34,6 +35,7 @@ pub async fn subscribe(
form: web::Form<FormData>, form: web::Form<FormData>,
pool: web::Data<PgPool>, pool: web::Data<PgPool>,
email_client: web::Data<EmailClient>, email_client: web::Data<EmailClient>,
application_url: web::Data<ApplicationUrl>,
) -> Result<HttpResponse, HttpResponse> { ) -> Result<HttpResponse, HttpResponse> {
let new_subscriber = form let new_subscriber = form
.0 .0
@ -43,19 +45,20 @@ pub async fn subscribe(
.await .await
.map_err(|_| HttpResponse::InternalServerError().finish())?; .map_err(|_| HttpResponse::InternalServerError().finish())?;
// We are swallowing the error for the time being. // We are swallowing the error for the time being.
let _ = send_confirmation_email(&email_client, new_subscriber).await; let _ = send_confirmation_email(&email_client, new_subscriber, &application_url.0).await;
Ok(HttpResponse::Ok().finish()) Ok(HttpResponse::Ok().finish())
} }
#[tracing::instrument( #[tracing::instrument(
name = "Send a confirmation email to a new subscriber", name = "Send a confirmation email to a new subscriber",
skip(email_client, new_subscriber) skip(email_client, new_subscriber, application_url)
)] )]
pub async fn send_confirmation_email( pub async fn send_confirmation_email(
email_client: &EmailClient, email_client: &EmailClient,
new_subscriber: NewSubscriber, new_subscriber: NewSubscriber,
application_url: &str,
) -> Result<(), reqwest::Error> { ) -> Result<(), reqwest::Error> {
let confirmation_link = "https://my-api.com/subscriptions/confirm"; let confirmation_link = format!("{}/subscriptions/confirm", application_url);
let plain_body = format!( let plain_body = format!(
"Welcome to our newsletter!\nVisit {} to confirm your subscription.", "Welcome to our newsletter!\nVisit {} to confirm your subscription.",
confirmation_link confirmation_link

View file

@ -36,7 +36,12 @@ impl Application {
); );
let listener = TcpListener::bind(&address)?; let listener = TcpListener::bind(&address)?;
let port = listener.local_addr().unwrap().port(); let port = listener.local_addr().unwrap().port();
let server = run(listener, connection_pool, email_client)?; let server = run(
listener,
connection_pool,
email_client,
configuration.application.url,
)?;
Ok(Self { port, server }) Ok(Self { port, server })
} }
@ -57,10 +62,13 @@ pub async fn get_connection_pool(configuration: &DatabaseSettings) -> Result<PgP
.await .await
} }
pub struct ApplicationUrl(pub String);
fn run( fn run(
listener: TcpListener, listener: TcpListener,
db_pool: PgPool, db_pool: PgPool,
email_client: EmailClient, email_client: EmailClient,
application_url: String,
) -> Result<Server, std::io::Error> { ) -> Result<Server, std::io::Error> {
let db_pool = Data::new(db_pool); let db_pool = Data::new(db_pool);
let email_client = Data::new(email_client); let email_client = Data::new(email_client);
@ -71,6 +79,7 @@ fn run(
.route("/subscriptions", web::post().to(subscribe)) .route("/subscriptions", web::post().to(subscribe))
.app_data(db_pool.clone()) .app_data(db_pool.clone())
.app_data(email_client.clone()) .app_data(email_client.clone())
.data(ApplicationUrl(application_url.clone()))
}) })
.listen(listener)? .listen(listener)?
.run(); .run();

View file

@ -33,6 +33,8 @@ impl TestApp {
} }
pub async fn spawn_app() -> TestApp { pub async fn spawn_app() -> TestApp {
lazy_static::initialize(&TRACING);
// Launch a mock server to stand in for Postmark's API // Launch a mock server to stand in for Postmark's API
let email_server = MockServer::start().await; let email_server = MockServer::start().await;

View file

@ -118,15 +118,16 @@ async fn the_link_returned_by_subscribe_sets_a_subscriber_as_confirmed() {
}; };
let confirmation_link = Url::parse(&get_link(&body["HtmlBody"].as_str().unwrap())).unwrap(); 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 // Let's make sure we don't call random APIs on the web
assert_eq!(confirmation_link.domain().unwrap(), "127.0.0.1"); assert_eq!(confirmation_link.host_str().unwrap(), "127.0.0.1");
// Let's rewrite the URL to include the port
let confirmation_link = format!("{}{}", app.address, confirmation_link.path());
// Act // Act
let response = reqwest::get(confirmation_link) let response = reqwest::get(&confirmation_link)
.await .await
.unwrap() .unwrap()
.error_for_status() .error_for_status()
.unwrap(); .unwrap();
dbg!(&response);
// Assert // Assert
let saved = sqlx::query!(r#"SELECT status FROM subscriptions WHERE name = 'le guin' AND email = 'ursula_le_guin@gmail.com'"#,) let saved = sqlx::query!(r#"SELECT status FROM subscriptions WHERE name = 'le guin' AND email = 'ursula_le_guin@gmail.com'"#,)