add rough subscribe endpoint (3.7)

This commit is contained in:
azdle 2025-05-14 13:57:31 -05:00
parent 49c418068e
commit b5c443506e
3 changed files with 92 additions and 2 deletions

View file

@ -1,14 +1,15 @@
mod auth;
mod subscriptions;
use axum::{routing::get, Router};
use super::AppState;
pub fn build() -> Router<AppState> {
let auth = auth::build();
Router::new()
.route("/health", get(health_check))
.nest("/auth", auth)
.nest("/auth", auth::build())
.nest("/subscriptions", subscriptions::build())
}
// just always returns a 200 OK for now, the server has no state, if it's up, it's working

View file

@ -0,0 +1,38 @@
use axum::{http::StatusCode, response::IntoResponse, routing::post, Form, Router};
use serde::Deserialize;
use tracing::info;
use crate::server::AppState;
pub fn build() -> Router<AppState> {
Router::new().route("/", post(subscribe))
}
#[derive(Deserialize)]
pub struct SubscribeForm {
name: Option<String>,
email: String,
}
pub async fn subscribe(Form(form): Form<SubscribeForm>) -> Result<(), SubscribeError> {
info!(form.name, form.email, "subscribe attempt");
if form.email.is_empty() {
return Err(SubscribeError::InvalidEmail);
}
Ok(())
}
pub enum SubscribeError {
InvalidEmail,
}
impl IntoResponse for SubscribeError {
fn into_response(self) -> axum::response::Response {
match self {
SubscribeError::InvalidEmail => (StatusCode::BAD_REQUEST, "Invalid Email Address"),
}
.into_response()
}
}

51
tests/subscriptions.rs Normal file
View file

@ -0,0 +1,51 @@
pub mod fixture;
use fixture::TestServer;
use anyhow::Result;
use test_log::test as traced;
#[traced(tokio::test)]
async fn subscribe_succeeds_with_valid_input() -> Result<()> {
let server = TestServer::spawn().await;
let client = reqwest::Client::builder().build()?;
// Subscribe
let resp = client
.post(server.url("/subscriptions"))
.header("Content-Type", "application/x-www-form-urlencoded")
.body("name=le%20guin&email=ursula_le_guin%40gmail.com")
.send()
.await?;
assert_eq!(resp.status(), 200, "subscribe succeeds");
server.shutdown().await
}
#[traced(tokio::test)]
async fn subscribe_fails_with_missing_data() -> Result<()> {
let server = TestServer::spawn().await;
let client = reqwest::Client::new();
let test_cases = [
("", "missing both name and email"),
("name=le%20guin", "missing the email"),
];
for (body, msg) in test_cases {
let resp = client
.post(server.url("/subscriptions"))
.header("Content-Type", "application/x-www-form-urlencoded")
.body(body)
.send()
.await?;
assert_eq!(
resp.status(),
422,
"subscribe fails with bad request when {msg}"
);
}
server.shutdown().await
}