From 1c2873b3059f3e4d6bd02307ec5b22f761ce1c80 Mon Sep 17 00:00:00 2001 From: Dawid Rycerz Date: Mon, 14 Jul 2025 20:35:00 +0300 Subject: feat: Update routes and fix issues --- src/weather_thresholds.rs | 153 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 135 insertions(+), 18 deletions(-) (limited to 'src/weather_thresholds.rs') diff --git a/src/weather_thresholds.rs b/src/weather_thresholds.rs index bfb9cdf..dadfeda 100644 --- a/src/weather_thresholds.rs +++ b/src/weather_thresholds.rs @@ -1,5 +1,12 @@ +use crate::auth::AuthUser; +use axum::Json; +use axum::extract::{Query, State}; +use axum::http::StatusCode; +use axum::response::IntoResponse; use serde::{Deserialize, Serialize}; use sqlx::FromRow; +use std::collections::HashMap; +use std::sync::Arc; #[derive(Debug, Serialize, Deserialize, FromRow, Clone, PartialEq)] pub struct WeatherThreshold { @@ -17,7 +24,10 @@ pub struct WeatherThresholdRepository<'a> { } impl<'a> WeatherThresholdRepository<'a> { - pub async fn list_thresholds(&self, user_id: i64) -> Result, sqlx::Error> { + pub async fn list_thresholds( + &self, + user_id: i64, + ) -> Result, sqlx::Error> { sqlx::query_as::<_, WeatherThreshold>( "SELECT id, user_id, condition_type, threshold_value, operator, enabled, description FROM weather_thresholds WHERE user_id = ?" ) @@ -26,7 +36,11 @@ impl<'a> WeatherThresholdRepository<'a> { .await } - pub async fn get_threshold(&self, id: i64, user_id: i64) -> Result, sqlx::Error> { + pub async fn get_threshold( + &self, + id: i64, + user_id: i64, + ) -> Result, sqlx::Error> { sqlx::query_as::<_, WeatherThreshold>( "SELECT id, user_id, condition_type, threshold_value, operator, enabled, description FROM weather_thresholds WHERE id = ? AND user_id = ?" ) @@ -36,7 +50,15 @@ impl<'a> WeatherThresholdRepository<'a> { .await } - pub async fn create_threshold(&self, user_id: i64, condition_type: String, threshold_value: f64, operator: String, enabled: bool, description: Option) -> Result { + pub async fn create_threshold( + &self, + user_id: i64, + condition_type: String, + threshold_value: f64, + operator: String, + enabled: bool, + description: Option, + ) -> Result { sqlx::query_as::<_, WeatherThreshold>( "INSERT INTO weather_thresholds (user_id, condition_type, threshold_value, operator, enabled, description) VALUES (?, ?, ?, ?, ?, ?) RETURNING id, user_id, condition_type, threshold_value, operator, enabled, description" ) @@ -50,7 +72,16 @@ impl<'a> WeatherThresholdRepository<'a> { .await } - pub async fn update_threshold(&self, id: i64, user_id: i64, condition_type: String, threshold_value: f64, operator: String, enabled: bool, description: Option) -> Result { + pub async fn update_threshold( + &self, + id: i64, + user_id: i64, + condition_type: String, + threshold_value: f64, + operator: String, + enabled: bool, + description: Option, + ) -> Result { sqlx::query_as::<_, WeatherThreshold>( "UPDATE weather_thresholds SET condition_type = ?, threshold_value = ?, operator = ?, enabled = ?, description = ? WHERE id = ? AND user_id = ? RETURNING id, user_id, condition_type, threshold_value, operator, enabled, description" ) @@ -75,11 +106,35 @@ impl<'a> WeatherThresholdRepository<'a> { } } +pub async fn list_thresholds( + AuthUser(_): AuthUser, + State(pool): State>, + Query(query): Query>, +) -> impl IntoResponse { + let repo = WeatherThresholdRepository { db: &pool }; + let user_id = match query.get("user_id").and_then(|s| s.parse().ok()) { + Some(uid) => uid, + None => { + return crate::error_response( + StatusCode::BAD_REQUEST, + "user_id required as query param", + ); + } + }; + match repo.list_thresholds(user_id).await { + Ok(thresholds) => Json(thresholds).into_response(), + Err(e) => crate::error_response(StatusCode::INTERNAL_SERVER_ERROR, &e.to_string()), + } +} + #[cfg(test)] mod tests { use super::*; use crate::users::{UserRepository, UserRole}; - use sqlx::{SqlitePool, Executor}; + use axum::extract::{Json, State}; + use hyper::StatusCode; + use sqlx::{Executor, SqlitePool}; + use std::sync::Arc; use tokio; async fn setup_db() -> SqlitePool { @@ -89,8 +144,10 @@ mod tests { id INTEGER PRIMARY KEY AUTOINCREMENT, user_id TEXT NOT NULL UNIQUE, role TEXT NOT NULL DEFAULT 'user' - );" - ).await.unwrap(); + );", + ) + .await + .unwrap(); pool.execute( "CREATE TABLE weather_thresholds ( id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -101,8 +158,10 @@ mod tests { enabled BOOLEAN NOT NULL DEFAULT 1, description TEXT, FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE - );" - ).await.unwrap(); + );", + ) + .await + .unwrap(); pool } @@ -117,12 +176,21 @@ mod tests { let db = setup_db().await; let user_id = create_user(&db).await; let repo = WeatherThresholdRepository { db: &db }; - let th = repo.create_threshold(user_id, "wind_speed".to_string(), 10.0, ">".to_string(), true, Some("desc".to_string())).await.unwrap(); + let th = repo + .create_threshold( + user_id, + "wind_speed".to_string(), + 10.0, + ">".to_string(), + true, + Some("desc".to_string()), + ) + .await + .unwrap(); let fetched = repo.get_threshold(th.id, user_id).await.unwrap().unwrap(); assert_eq!(fetched.condition_type, "wind_speed"); assert_eq!(fetched.threshold_value, 10.0); - assert_eq!(fetched.operator, ">" - ); + assert_eq!(fetched.operator, ">"); assert_eq!(fetched.enabled, true); assert_eq!(fetched.description, Some("desc".to_string())); } @@ -132,8 +200,29 @@ mod tests { let db = setup_db().await; let user_id = create_user(&db).await; let repo = WeatherThresholdRepository { db: &db }; - let th = repo.create_threshold(user_id, "wind_speed".to_string(), 10.0, ">".to_string(), true, None).await.unwrap(); - let updated = repo.update_threshold(th.id, user_id, "rain".to_string(), 5.0, "<".to_string(), false, Some("rain desc".to_string())).await.unwrap(); + let th = repo + .create_threshold( + user_id, + "wind_speed".to_string(), + 10.0, + ">".to_string(), + true, + None, + ) + .await + .unwrap(); + let updated = repo + .update_threshold( + th.id, + user_id, + "rain".to_string(), + 5.0, + "<".to_string(), + false, + Some("rain desc".to_string()), + ) + .await + .unwrap(); assert_eq!(updated.condition_type, "rain"); assert_eq!(updated.threshold_value, 5.0); assert_eq!(updated.operator, "<"); @@ -146,7 +235,17 @@ mod tests { let db = setup_db().await; let user_id = create_user(&db).await; let repo = WeatherThresholdRepository { db: &db }; - let th = repo.create_threshold(user_id, "wind_speed".to_string(), 10.0, ">".to_string(), true, None).await.unwrap(); + let th = repo + .create_threshold( + user_id, + "wind_speed".to_string(), + 10.0, + ">".to_string(), + true, + None, + ) + .await + .unwrap(); repo.delete_threshold(th.id, user_id).await.unwrap(); let fetched = repo.get_threshold(th.id, user_id).await.unwrap(); assert!(fetched.is_none()); @@ -157,9 +256,27 @@ mod tests { let db = setup_db().await; let user_id = create_user(&db).await; let repo = WeatherThresholdRepository { db: &db }; - repo.create_threshold(user_id, "wind_speed".to_string(), 10.0, ">".to_string(), true, None).await.unwrap(); - repo.create_threshold(user_id, "rain".to_string(), 5.0, "<".to_string(), false, None).await.unwrap(); + repo.create_threshold( + user_id, + "wind_speed".to_string(), + 10.0, + ">".to_string(), + true, + None, + ) + .await + .unwrap(); + repo.create_threshold( + user_id, + "rain".to_string(), + 5.0, + "<".to_string(), + false, + None, + ) + .await + .unwrap(); let thresholds = repo.list_thresholds(user_id).await.unwrap(); assert_eq!(thresholds.len(), 2); } -} \ No newline at end of file +} -- cgit v1.2.3