Remove name from subscriptions table
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
mod new_subscriber;
|
||||
mod subscriber_email;
|
||||
mod subscriber_name;
|
||||
|
||||
pub use new_subscriber::NewSubscriber;
|
||||
pub use subscriber_email::SubscriberEmail;
|
||||
pub use subscriber_name::SubscriberName;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use crate::domain::{SubscriberName, subscriber_email::SubscriberEmail};
|
||||
use crate::domain::subscriber_email::SubscriberEmail;
|
||||
|
||||
pub struct NewSubscriber {
|
||||
pub email: SubscriberEmail,
|
||||
pub name: SubscriberName,
|
||||
}
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SubscriberName(String);
|
||||
|
||||
impl SubscriberName {
|
||||
pub fn parse(s: String) -> Result<Self, String> {
|
||||
let is_empty_or_whitespace = s.trim().is_empty();
|
||||
let is_too_long = s.graphemes(true).count() > 256;
|
||||
let forbidden_characters = ['/', '(', ')', '"', '<', '>', '\\', '{', '}'];
|
||||
let contains_forbidden_characters = s.chars().any(|g| forbidden_characters.contains(&g));
|
||||
|
||||
if is_empty_or_whitespace || is_too_long || contains_forbidden_characters {
|
||||
Err(format!("{} is not a valid subscriber name.", s))
|
||||
} else {
|
||||
Ok(Self(s))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for SubscriberName {
|
||||
fn as_ref(&self) -> &str {
|
||||
self.0.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::domain::SubscriberName;
|
||||
use claims::{assert_err, assert_ok};
|
||||
|
||||
#[test]
|
||||
fn a_256_grapheme_long_name_is_valid() {
|
||||
let name = "ê".repeat(256);
|
||||
assert_ok!(SubscriberName::parse(name));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_name_longer_than_256_graphemes_is_rejected() {
|
||||
let name = "ê".repeat(257);
|
||||
assert_err!(SubscriberName::parse(name));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_whitespace_only_name_is_rejected() {
|
||||
let name = "\n \t ".to_string();
|
||||
assert_err!(SubscriberName::parse(name));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_string_is_rejected() {
|
||||
let name = "".to_string();
|
||||
assert_err!(SubscriberName::parse(name));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_name_containing_invalid_character_is_rejected() {
|
||||
for name in ['/', '(', ')', '"', '<', '>', '\\', '{', '}'] {
|
||||
let name = name.to_string();
|
||||
assert_err!(SubscriberName::parse(name));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_valid_name_is_parsed_successfully() {
|
||||
let name = "Alphonse".to_string();
|
||||
assert_ok!(SubscriberName::parse(name));
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
domain::{NewSubscriber, SubscriberEmail, SubscriberName},
|
||||
domain::{NewSubscriber, SubscriberEmail},
|
||||
email_client::EmailClient,
|
||||
startup::AppState,
|
||||
};
|
||||
@@ -82,7 +82,6 @@ impl IntoResponse for SubscribeError {
|
||||
skip(messages, connection_pool, email_client, base_url, form),
|
||||
fields(
|
||||
subscriber_email = %form.email,
|
||||
subscriber_name = %form.name
|
||||
)
|
||||
)]
|
||||
pub async fn subscribe(
|
||||
@@ -140,12 +139,11 @@ pub async fn insert_subscriber(
|
||||
let subscriber_id = Uuid::new_v4();
|
||||
let query = sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO subscriptions (id, email, name, subscribed_at, status)
|
||||
VALUES ($1, $2, $3, $4, 'pending_confirmation')
|
||||
INSERT INTO subscriptions (id, email, subscribed_at, status)
|
||||
VALUES ($1, $2, $3, 'pending_confirmation')
|
||||
"#,
|
||||
subscriber_id,
|
||||
new_subscriber.email.as_ref(),
|
||||
new_subscriber.name.as_ref(),
|
||||
Utc::now()
|
||||
);
|
||||
transaction.execute(query).await?;
|
||||
@@ -209,20 +207,14 @@ Click <a href=\"{}\">here</a> to confirm your subscription.",
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[allow(dead_code)]
|
||||
pub struct SubscriptionFormData {
|
||||
name: String,
|
||||
email: String,
|
||||
email_check: String,
|
||||
}
|
||||
|
||||
impl TryFrom<SubscriptionFormData> for NewSubscriber {
|
||||
type Error = String;
|
||||
|
||||
fn try_from(value: SubscriptionFormData) -> Result<Self, Self::Error> {
|
||||
let name = SubscriberName::parse(value.name)?;
|
||||
if value.email != value.email_check {
|
||||
return Err("Email addresses don't match.".into());
|
||||
}
|
||||
let email = SubscriberEmail::parse(value.email)?;
|
||||
Ok(Self { name, email })
|
||||
Ok(Self { email })
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user