use actix_web::{web, HttpResponse}; use diesel::RunQueryDsl; use crate::{ auth::extractor::AuthUser, database::establish_connection, json_serialization::new_feed::NewFeedSchema, models::feed::new_feed::NewFeed, schema::feed, }; use super::feeds; pub async fn add(new_feed: web::Json, auth_user: AuthUser) -> HttpResponse { if auth_user.0 != new_feed.user_id { return HttpResponse::Forbidden().finish(); } let mut connection = establish_connection(); let title: String = new_feed.title.clone(); let url: String = new_feed.url.clone(); let user_id: i32 = new_feed.user_id; let result = feeds::get_feed(&url).await; match result { Ok(channel) => { log::info!("valid channel"); if channel.items.is_empty() { return HttpResponse::ServiceUnavailable().finish(); } } Err(e) => { log::error!("{:?}", e); return HttpResponse::NotFound().finish(); } } let new_feed = NewFeed::new(title, url, user_id); let insert_result = diesel::insert_into(feed::table) .values(&new_feed) .execute(&mut connection); match insert_result { Ok(_) => HttpResponse::Created().finish(), Err(e) => { log::error!("{e}"); HttpResponse::Conflict().finish() } } } #[cfg(test)] mod tests { use actix_service::Service; use actix_web::http::StatusCode; use actix_web::{test, web, App, HttpMessage}; use super::add; use crate::auth::extractor::AuthUser; use crate::test_helpers::unique_suffix; #[actix_web::test] async fn add_fails_for_unfetchable_feed_url() { let app = test::init_service( App::new() .wrap_fn(move |req, srv| { req.extensions_mut().insert(AuthUser(1)); srv.call(req) }) .route("/add", web::post().to(add)), ) .await; let req = test::TestRequest::post() .uri("/add") .set_json(serde_json::json!({ "title": "Bad feed", "url": format!("not-a-valid-url-{}", unique_suffix()), "user_id": 1 })) .to_request(); let resp = test::call_service(&app, req).await; assert_eq!(StatusCode::NOT_FOUND, resp.status()); } #[actix_web::test] async fn add_rejects_feed_for_another_user() { let app = test::init_service( App::new() .wrap_fn(move |req, srv| { req.extensions_mut().insert(AuthUser(1)); srv.call(req) }) .route("/add", web::post().to(add)), ) .await; let req = test::TestRequest::post() .uri("/add") .set_json(serde_json::json!({ "title": "Someone else's feed", "url": format!("https://example.test/feed/{}", unique_suffix()), "user_id": 2 })) .to_request(); let resp = test::call_service(&app, req).await; assert_eq!(StatusCode::FORBIDDEN, resp.status()); } }