116 lines
3.7 KiB
Rust
Executable File
116 lines
3.7 KiB
Rust
Executable File
use crate::json_serialization::user::JsonUser;
|
|
use crate::models::feed::rss_feed::Feed;
|
|
use crate::models::feed_item::rss_feed_item::FeedItem;
|
|
use crate::reader::structs::feed::FeedAggregate;
|
|
use crate::schema::feed_item::{feed_id, id, read};
|
|
use crate::{
|
|
database::establish_connection,
|
|
json_serialization::articles::Articles,
|
|
schema::feed::{self, user_id},
|
|
schema::feed_item,
|
|
};
|
|
use actix_web::{web, HttpRequest, Responder};
|
|
use chrono::Local;
|
|
use diesel::prelude::*;
|
|
|
|
use super::structs::article::Article;
|
|
|
|
pub async fn get(path: web::Path<JsonUser>, req: HttpRequest) -> impl Responder {
|
|
let request = req.clone();
|
|
let req_user_id = path.user_id;
|
|
log::info!("Received user_id: {}", req_user_id);
|
|
|
|
let mut connection: diesel::PgConnection = establish_connection();
|
|
let feeds: Vec<Feed> = feed::table
|
|
.filter(user_id.eq(req_user_id))
|
|
.load::<Feed>(&mut connection)
|
|
.unwrap();
|
|
|
|
let mut feed_aggregates: Vec<FeedAggregate> = Vec::new();
|
|
for feed in feeds {
|
|
let existing_item: Vec<FeedItem> = feed_item::table
|
|
.filter(feed_id.eq(feed.id))
|
|
.filter(read.eq(false))
|
|
.order(id.asc())
|
|
.load(&mut connection)
|
|
.unwrap();
|
|
|
|
log::info!(
|
|
"Load {} feed items for feed: {}",
|
|
existing_item.len(),
|
|
feed.url
|
|
);
|
|
|
|
let article_list: Vec<Article> = existing_item
|
|
.into_iter()
|
|
.map(|feed_item: FeedItem| {
|
|
let time: String = match feed_item.created_ts {
|
|
Some(r) => r.to_string(),
|
|
None => Local::now().naive_local().to_string(),
|
|
};
|
|
Article {
|
|
title: feed_item.title,
|
|
content: feed_item.content,
|
|
url: feed_item.url,
|
|
timestamp: time,
|
|
id: feed_item.id,
|
|
}
|
|
})
|
|
.collect();
|
|
|
|
log::info!("article list with {} items generated.", article_list.len());
|
|
|
|
feed_aggregates.push(FeedAggregate {
|
|
title: feed.title,
|
|
items: article_list,
|
|
})
|
|
}
|
|
|
|
let articles: Articles = Articles {
|
|
feeds: feed_aggregates,
|
|
};
|
|
|
|
articles.respond_to(&request)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use actix_web::http::StatusCode;
|
|
use actix_web::{test, web, App};
|
|
|
|
use super::get;
|
|
use crate::database::establish_connection;
|
|
use crate::test_helpers::{
|
|
delete_feed, delete_feed_item, delete_user, insert_feed, insert_feed_item, insert_user,
|
|
};
|
|
|
|
#[actix_web::test]
|
|
async fn get_returns_only_unread_items() {
|
|
let mut connection = establish_connection();
|
|
let user = insert_user(&mut connection, "secret");
|
|
let feed = insert_feed(&mut connection, user.id);
|
|
let unread = insert_feed_item(&mut connection, feed.id, false);
|
|
let read = insert_feed_item(&mut connection, feed.id, true);
|
|
|
|
let app =
|
|
test::init_service(App::new().route("/get/{user_id}", web::get().to(get))).await;
|
|
let req = test::TestRequest::get()
|
|
.uri(&format!("/get/{}", user.id))
|
|
.to_request();
|
|
let resp = test::call_service(&app, req).await;
|
|
|
|
assert_eq!(StatusCode::OK, resp.status());
|
|
|
|
let body = test::read_body(resp).await;
|
|
let body_str = String::from_utf8(body.to_vec()).unwrap();
|
|
|
|
assert!(body_str.contains(&unread.title));
|
|
assert!(!body_str.contains(&read.title));
|
|
|
|
delete_feed_item(&mut connection, unread.id);
|
|
delete_feed_item(&mut connection, read.id);
|
|
delete_feed(&mut connection, feed.id);
|
|
delete_user(&mut connection, user.id);
|
|
}
|
|
}
|